Эй. Я плохо знаком с ANTLR. Мастер ANTLRWorks wrrited для меня следующий код:
grammar test;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : '0'..'9'+
;
FLOAT
: ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
| '.' ('0'..'9')+ EXPONENT?
| ('0'..'9')+ EXPONENT
;
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
STRING
: '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
;
CHAR: '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
;
fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
fragment
OCTAL_ESC
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESC
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
При отладке его он бросает следующую ошибку:
[22:45:49] error(100): C:\Documents and Settings\user\Desktop\test.g:0:0: syntax error: codegen: <AST>:0:0: unexpected end of subtree
Кто-то может объяснить меня, какова ошибка, где это и как я могу зафиксировать его?
Спасибо.
В ANTLR каждое правило, которое начинается с верхнего регистра, является правилом лексера. Те, которые начинаются с нижнего регистра, являются правилами синтаксического анализатора. Как видите, у вас есть только правила лексера: и в этом ваша проблема. У вас должно быть хотя бы одно правило парсера. Если вы добавите следующее правило:
parse
: ID
| INT
| // ...
;
ошибка исчезнет при создании исходных файлов для вашего лексера / парсера.
Заявление об ограничении ответственности: я ничего не знаю о мастере ANTLR.
Поиск в Google показывает эту цитату:
Обычно «неожиданный конец поддерева» означает, что вы забыли сделать что-то root в парсере.
Для меня это имеет смысл, ЕСЛИ ваш файл должен определять грамматику, а не только правила лексического анализа. Первая строка вашего файла - это «грамматический тест», так что, по-видимому, это грамматика.
Грамматика позволяет вам сократить серию терминальных символов до одного нетерминального символа. Так, например, очень простая грамматика, представляющая полностью заключенные в скобки выражения, будет выглядеть так:
P : E
E : (X)
| E E
| (E)
X : 'x'
Здесь P является корнем, потому что все предложения в конечном итоге сводятся к P. Если предложение не может быть сокращено до P, оно не соответствует этой грамматике. . Итак, вам нужно найти корень для вашей грамматики, а все остальные произведения должны возникать только в контексте корня (т.е. через прямое или косвенное происхождение).