Stackoverflow.
Продолжение моего путешествия в Antlr (предыдущие вопросы могут дать дополнительные подсказки о том, чего я пытаюсь достичь! Q1 - Как мне сделать синтаксический анализатор деревьев и Q2 - Решение проблемы рекурсии LL ) Я столкнулся с еще одним блокпостом, который не могу понять.
В принципе (я полагаю) правило expression
в моей грамматике должно либо создавать новый корневой узел, в зависимости от количества совпадений datatype
s, которым оно соответствует. Я собрал пример, чтобы лучше описать, что я имею в виду:
С учетом следующего ввода:
ComplexFunction(id="Test" args:[1, 25 + 9 + 8, true, [1,2,3]])
Я получаю это дерево:
http://img25.imageshack.us/img25/2273/treeka.png
Для справки - первый элемент в массиве "args" был правильно проанализирован. Тогда как 2-й элемент в массиве «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'|'\"'|'\''|'\\')
;