我从未使用过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”
是一个单词(大写,小写字母,数字,'_')
是 的同一个词,但前面加上文字“ end _”
可以是任何字符
这是我到目前为止所做的:
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
warning(146):MyGrammar.g4:45:0:非片段词法分析器规则TEXT可以匹配空字符串
$ javac MyGrammar * .java
$ grun MyGrammar根令牌-
CMD.NEW
[@ 0,0:6 ='CMD.NEW',
,1:0] [@ 1,7:7 ='\ n',
,1:7] [@ 2,8:7 ='
', ,2:0]
问题在于“ CMD.NEW”被TEXT吞噬了,因为该规则很贪婪。
有人可以帮助我吗? 谢谢
答案 0 :(得分:2)
存在语法歧义。
在您提供的示例中,CMD.NEW
可以与command_line
和normal_line
匹配。
因此,给出表达式:
line : (comment_line | command_line | normal_line) NEWLINE;
解析器不能肯定地说出要接受的规则(command_line
或normal_line
),因此它与实际上是简单的normal_line
的{{1}}相匹配。
考虑以解析器始终可以说出要接受的规则的方式来重写语法。
更新:
尝试一下(我没有测试过,但是应该可以):
TEXT