2010-01-25 35 views
3

Stackoverflow。Antrl3條件樹重寫

我的旅程ANTLR的持續(以前的問題可以提供更多的線索上我想要實現的!Q1 - How do I make a tree parserQ2 - Solving LL recursion problem)我已經打了又一個障礙,我不能flathom。

基本上(我相信)我的語法中的expression規則需要創建一個新的根節點,具體取決於它匹配的datatype的數量。我已經把一個例子來嘗試最好的形容我的意思:

鑑於以下輸入:

ComplexFunction(id="Test" args:[1, 25 + 9 + 8, true, [1,2,3]]) 

我得到這個樹:

http://img25.imageshack.us/img25/2273/treeka.png

僅供參考 - 正確解析了「args」數組中的第一個元素。而數組「args」'25 + 9 + 8'中的第二個元素沒有。它似乎只匹配表達式(9 + 8)的最後2個部分。

我試圖讓數組的第二個元素是一個EXPRESSION節點,與3個孩子25,9和8)。

我老實說卡住了,需要你的幫助(再次)。感謝您的時間:)

供參考,這是我的語法:

grammar Test; 

options {output=AST;ASTLabelType=CommonTree;} 
tokens {FUNCTION; NAME; ATTRIBUTES; ATTRIBUTE; VALUE; CHILDREN; EXPRESSION;} 

program : function ; 
function : ID (OPEN_BRACKET (attribute (COMMA? attribute)*)? CLOSE_BRACKET)? (OPEN_BRACE function* CLOSE_BRACE)? SEMICOLON? -> ^(FUNCTION ^(NAME ID) ^(ATTRIBUTES attribute*) ^(CHILDREN function*)) ; 

attribute : ID (COLON | EQUALS) expression -> ^(ATTRIBUTE ^(NAME ID) ^(VALUE expression)); 

expression : datatype (PLUS datatype)* -> datatype ^(EXPRESSION datatype+)?; 

datatype : ID -> ^(STRING["ID"] ID) 
    | NUMBER -> ^(STRING["NUMBER"] NUMBER) 
    | STRING -> ^(STRING["STRING"] STRING) 
    | BOOLEAN -> ^(STRING["BOOLEAN"] BOOLEAN) 
    | array -> ^(STRING["ARRAY"] array) 
    | lookup -> ^(STRING["LOOKUP"] lookup) ; 

array : OPEN_BOX (expression (COMMA expression)*)? CLOSE_BOX -> expression* ; 

lookup : OPEN_BRACE (ID (PERIOD ID)*) CLOSE_BRACE -> ID* ; 

NUMBER 
: ('+' | '-')? (INTEGER | FLOAT) 
; 

STRING 
    : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
    ; 

BOOLEAN 
: 'true' | 'TRUE' | 'false' | 'FALSE' 
; 

ID : (LETTER|'_') (LETTER | INTEGER |'_')* 
    ; 

COMMENT 
    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} 
    | '/*' (options {greedy=false;} : .)* '*/' {$channel=HIDDEN;} 
    ; 

WHITESPACE : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ; 

COLON : ':' ; 
SEMICOLON : ';' ; 

COMMA : ',' ; 
PERIOD : '.' ; 
PLUS : '+' ; 
EQUALS : '=' ; 

OPEN_BRACKET : '(' ; 
CLOSE_BRACKET : ')' ; 

OPEN_BRACE : '{' ; 
CLOSE_BRACE : '}' ; 

OPEN_BOX : '[' ; 
CLOSE_BOX : ']' ; 

fragment 
LETTER 
: 'a'..'z' | 'A'..'Z' 
; 

fragment 
INTEGER 
: '0'..'9'+ 
; 

fragment 
FLOAT 
: INTEGER+ '.' INTEGER* 
; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    ; 
+0

任何人都? :( – 2010-01-25 23:00:20

回答

0

哈哈!我想我明白了!如果其他人有類似的問題,看看我的新語法:

grammar Test; 

options {output=AST;ASTLabelType=CommonTree;} 
tokens {FUNCTION; ATTRIBUTES; ATTRIBUTE; VALUE; CHILDREN; EXPRESSION;} 

@parser::members { int dataTypeCount = 0; } 

program  : function ; 
function : ID (OPEN_BRACKET (attribute (COMMA? attribute)*)? CLOSE_BRACKET)? (OPEN_BRACE function* CLOSE_BRACE)? SEMICOLON? -> ^(FUNCTION ^(ID["ID"] ID) ^(ATTRIBUTES attribute*) ^(CHILDREN function*)) ; 

attribute : ID (COLON | EQUALS) expression -> ^(ATTRIBUTE ^(ID["ID"] ID) ^(VALUE expression)); 

expression : datatype {dataTypeCount = 1;} (PLUS datatype {dataTypeCount++;})* 
       -> {dataTypeCount == 1}? datatype* 
       -> ^(EXPRESSION datatype*) ;  

datatype : ID  -> ^(STRING["ID"] ID) 
      | NUMBER -> ^(STRING["NUMBER"] NUMBER) 
      | STRING -> ^(STRING["STRING"] STRING) 
      | BOOLEAN -> ^(STRING["BOOLEAN"] BOOLEAN) 
      | array -> ^(STRING["ARRAY"] array) 
      | lookup -> ^(STRING["LOOKUP"] lookup) ; 

array  : OPEN_BOX (expression (COMMA expression)*)? CLOSE_BOX -> expression* ; 

lookup  : OPEN_BRACE (ID (PERIOD ID)*) CLOSE_BRACE -> ID* ; 

NUMBER 
    : ('+' | '-')? (INTEGER | FLOAT) 
    ; 

STRING 
    : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
    ; 

BOOLEAN 
    : 'true' | 'TRUE' | 'false' | 'FALSE' 
    ; 

ID : (LETTER|'_') (LETTER | INTEGER |'_')* 
    ; 

COMMENT 
    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} 
    | '/*' (options {greedy=false;} : .)* '*/' {$channel=HIDDEN;} 
    ; 

WHITESPACE : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ; 

COLON : ':' ; 
SEMICOLON : ';' ; 

COMMA : ',' ; 
PERIOD : '.' ; 
PLUS : '+' ; 
EQUALS : '=' ; 

OPEN_BRACKET : '(' ; 
CLOSE_BRACKET : ')' ; 

OPEN_BRACE : '{' ; 
CLOSE_BRACE : '}' ; 

OPEN_BOX : '[' ; 
CLOSE_BOX : ']' ; 

fragment 
LETTER 
    : 'a'..'z' | 'A'..'Z' 
    ; 

fragment 
INTEGER 
    : '0'..'9'+ 
    ; 

fragment 
FLOAT 
    : INTEGER+ '.' INTEGER* 
    ; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    ;