相关疑难解决方法(0)

与类似字符串匹配的Antlr lexer标记,如果贪婪的词法分子犯了错误怎么办?

似乎有时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)

antlr

5
推荐指数
1
解决办法
2089
查看次数

Lexer意外地标记了

以下非常简单的示例语法不像我预期的那样(根本没有).

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?开头的所有字符串来执行此操作?
  • 如果有一个额外的角色,为什么词法分子不会尝试这样做呢?
  • 我应该如何改变这种语法来解析我的预期方式?

antlr lexer antlr3

4
推荐指数
1
解决办法
174
查看次数

标签 统计

antlr ×2

antlr3 ×1

lexer ×1