Я никогда не работал с ANTLR и порождающими грамматиками, так что это моя первая попытка.
У меня есть собственный язык, который мне нужно проанализировать.Вот пример:
-- This is a comment
CMD.CMD1:foo_bar_123
CMD.CMD2
CMD.CMD4:9 of 28 (full)
CMD.NOTES:
This is an note.
A line
(1) there could be anything here foo_bar_123 & $ £ _ , . ==> BOOM
(3) same here
CMD.END_NOTES:
Вкратце, может быть 4 типа строк:
1) -- comment
2) <section>.<command>
3) <section>.<command>: <arg>
4) <section>.<command>:
<arg1>
<arg2>
...
<section>.<end_command>:
- это буквальное "CMD" - это одно слово (заглавные, строчные буквы, цифры, '_')
это то же слово, что и , но перед ним стоит буквальный "конец _"
может быть любым символом
Вот что я сделал до сих пор:
grammar MyGrammar;
/*
* Parser Rules
*/
root : line+ EOF ;
line : (comment_line | command_line | normal_line) NEWLINE;
comment_line : COMMENT ;
command_line : section '.' command ((COLON WHITESPACE*)? arg)? ;
normal_line : TEXT ;
section : CMD ;
command : WORD ;
arg : TEXT ;
/*
* Lexer Rules
*/
fragment LOWERCASE : [a-z] ;
fragment UPPERCASE : [A-Z] ;
fragment DIGIT : [0-9] ;
NUMBER : DIGIT+ ([.,] DIGIT+)? ;
CMD : 'CMD';
COLON : ':' ;
COMMENT : '--' ~[\r\n]*;
WHITESPACE : (' ' | '\t') ;
NEWLINE : ('\r'? '\n' | '\r')+;
WORD : (LOWERCASE | UPPERCASE | NUMBER | '_')+ ;
TEXT : ~[\r\n]* ;
Это тест для моей грамматики:
$ antlr4 MyGrammar.g4
предупреждение (146): MyGrammar.g4: 45: 0: не фрагментПравило лексера TEXT может соответствовать пустой строке
$ javac MyGrammar * .java
$ grun Корень MyGrammar -tokens
CMD.NEW
[@ 0, 0: 6 = 'CMD.NEW', , 1: 0]
[@ 1,7: 7 = '\ n', , 1: 7]
[@ 2,8: 7 = '', , 2: 0]
Проблема в том, что «CMD.NEW» проглатывается TEXT, потому что это правиложадный.
Кто-нибудь может мне помочь с этим?Спасибо