Java 什么';我简单的antlr语法有什么问题?

Java 什么';我简单的antlr语法有什么问题?,java,antlr,Java,Antlr,我正在尝试创建一个非常简单的antlr语法文件,该文件应解析以下文件: Report (MyReport) Begin End 或无报告名称: Report Begin End 这是我的语法文件: grammar RL; options { language = Java; } report: REPORT ('(' SPACE* STRING_LITERAL SPACE* ')')? BEGIN END ; REPORT : 'Report'

我正在尝试创建一个非常简单的antlr语法文件,该文件应解析以下文件:

Report (MyReport)
Begin
End
或无报告名称:

Report
Begin
End
这是我的语法文件:

grammar RL;

options {
  language = Java;
}

report:
  REPORT ('(' SPACE* STRING_LITERAL SPACE* ')')?
  BEGIN
  END
  ;

REPORT
    :   'Report'
    ;     

BEGIN
    :   'Begin'
    ;

END :   'End';

NAME:   LETTER (LETTER | DIGIT | '_')*;

STRING_LITERAL :    NAME SPACE*;

fragment LETTER: LOWER | UPPER;

fragment LOWER: 'a'..'z';

fragment UPPER: 'A'..'Z';

fragment DIGIT: '0'..'9';

fragment SPACE: ' ' | '\t';

WHITESPACE: SPACE+ { $channel = HIDDEN; };

rule: ;
但是,当我在AntlWorks中调试时,总是会出现以下错误:

 root -> report -> MismatchedTokenException(0!=0)
我的语法文件怎么了

谢谢, 格林说了几句话:

  • Java
    是默认语言,因此可以省略
    language=Java
    
  • 您正在解析器规则内使用
    空格
    ,而此
    空格
    标记是一个
    片段
    :这会导致lexer从不创建此标记:将其从解析器规则中删除
  • 输入的
    “Report”
    (“Report”后跟一个空格)被标记为
    字符串_LITERAL
    ,而不是
    报告
    !ANTLR的lexer贪婪地使用字符,只有当两个或多个规则匹配相同数量的字符时,首先定义的规则才会优先。lexer不会产生解析器试图匹配的标记(解析和标记化是独立执行的!)
请尝试以下操作:

grammar RL;

report
 : REPORT ('(' NAME ')')? BEGIN END
 ;

REPORT : 'Report';     
BEGIN  : 'Begin';
END    : 'End';
NAME   : LETTER (LETTER | DIGIT | '_')*;

fragment LETTER : LOWER | UPPER;
fragment LOWER  : 'a'..'z';
fragment UPPER  : 'A'..'Z';
fragment DIGIT  : '0'..'9';

SPACE  : (' ' | '\t' | '\r' | '\n')+ { $channel = HIDDEN; };
格林写道:

如果我想在报告名称中允许“空格”怎么办

我仍然会跳过lexer中的空格。接受名称之间的空格,但在其他上下文中忽略它们将导致一些笨拙的规则。我不会考虑报告名称之间的空格,而是这样做:

report
 : REPORT ('(' report_name ')')? BEGIN END
 ;

report_name
 : NAME+
 ;
生成以下解析树:

对于输入:

Report (a name with spaces) Begin End
非常感谢你。如果我想在报告名称中允许“空格”怎么办?我遵循了“报告名称”的方法,得到了这个错误:“T:\tmp\RL\RL.g:11:1:以下标记定义永远无法匹配,因为先前的标记匹配相同的输入:报告名称”。源代码位于@green,不,您没有遵循该方法。您使用了lexer规则
REPORT\u NAME
,而我使用了解析器规则
REPORT\u NAME
。确保你理解两者之间的区别:嗯。。。这真的很棘手。太多了!现在我已经成功了。新问题是我不能在报告名称中使用“报告”一词,它将报告
UnwantedTokenException(found=Report)
。我想这是因为我定义了
REPORT:“REPORT”,那么是否允许我在名称中使用“Report”等保留字?@green,请参阅我的修订答案。
report_name
 : (NAME | REPORT | BEGIN | END)+
 ;