ANTLR:有关贪婪规则的问题

时间:2019-03-09 14:31:22

标签: parsing antlr grammar lexer

我从未使用过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吞噬了,因为该规则很贪婪。

有人可以帮助我吗? 谢谢

1 个答案:

答案 0 :(得分:2)

存在语法歧义。

在您提供的示例中,CMD.NEW可以与command_linenormal_line匹配。
因此,给出表达式:

 line                : (comment_line | command_line | normal_line) NEWLINE;

解析器不能肯定地说出要接受的规则(command_linenormal_line),因此它与实际上是简单的normal_line的{​​{1}}相匹配。

考虑以解析器始终可以说出要接受的规则的方式来重写语法。

更新:

尝试一下(我没有测试过,但是应该可以):

TEXT