似乎有时Antlr词法分析器在对字符流进行标记时使用哪个规则做出了错误的选择......我正在试图弄清楚如何帮助Antlr做出明显的人性化选择.我想解析这样的文字:
d/dt(x)=a
a=d/dt
d=3
dt=4
Run Code Online (Sandbox Code Playgroud)
这是一种现有语言使用的不幸语法,我正在尝试编写解析器."d/dt(x)"表示微分方程的左侧.如果必须,请忽略行话,只要知道它不是"d"除以"dt".然而,第二次出现的"d/dt"确实是"d"除以"dt".
这是我的语法:
grammar diffeq_grammar;
program : (statement? NEWLINE)*;
statement
: diffeq
| assignment;
diffeq : DDT ID ')' '=' ID;
assignment
: ID '=' NUMBER
| ID '=' ID '/' ID
;
DDT : 'd/dt(';
ID : 'a'..'z'+;
NUMBER : '0'..'9'+;
NEWLINE : '\r\n'|'\r'|'\n';
Run Code Online (Sandbox Code Playgroud)
当使用这个语法时,词法分析器抓住第一个"d/dt("并将其转换为令牌DDT.完美!现在,词法分析器看到第二个"d"后跟一个"/"并说"嗯,我可以匹配这个作为一个ID和一个'/',或者我可以贪婪并匹配DDT".词法分析器选择贪婪...但它知之甚少,没有"("输入流后面的几个字符.当lexer查找缺少的"("它会抛出MismatchedTokenException!
到目前为止我找到的唯一解决方案是将所有规则移到解析器中,语法如下:
grammar diffeq_grammar;
program : (statement? NEWLINE)*;
statement
: diffeq
| assignment;
diffeq : ddt id ')' '=' id;
assignment
: id '=' number
| id '=' id '/' id …Run Code Online (Sandbox Code Playgroud) 以下非常简单的示例语法不像我预期的那样(根本没有).
Declaration : 'VAR';
Letter: ('A'..'Z');
message : Declaration Letter+;
Run Code Online (Sandbox Code Playgroud)
我所期望的结果是,任何字母序列都会作为单个字母而形成,并且序列"VAR"将被作为单个标记.
当我查看ANTLRWorks interperter时,我看到以下结果:
VARA解析message -> "VAR", "A"(预期)VARVA不解析(MismatchedTokenException(-1!= 5).词法分析器命中第二个VA并尝试标记Declaration.预期:message -> "VAR", "V", "A"VARVPP解析message -> "VAR", "V", "P", "P"(预期)VARVALL解析message -> "VAR", "VALL".我想帮助理解这种行为,并建议我如何解决这个问题.
特别:
VA为"声明",如果后跟一个字母?V?开头的所有字符串来执行此操作?