为什么我的语法适用于 *、-、/ 等运算符,但不适用于 +?

发布于 2024-10-20 08:59:07 字数 940 浏览 2 评论 0原文

我现在正在创建一个语法,我必须摆脱左递归,它似乎适用于除加法运算符之外的所有内容。

这是我的语法的相关部分:

SUBTRACT: '-';
PLUS: '+';
DIVIDE: '/';
MULTIPLY: '*';

expr: 
      (
        IDENTIFIER 
        | INTEGER 
        | STRING 
        | TRUE 
        | FALSE
      )
      (
        PLUS expr 
        | SUBTRACT expr 
        | MULTIPLY expr 
        | DIVIDE expr 
        | LESS_THAN expr 
        | LESS_THAN_OR_EQUAL expr 
        | EQUALS expr
      )*
      ;

INTEGER: ('0'..'9')*;
IDENTIFIER: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')*;

然后,当我尝试做类似的事情时,

x*1

它工作得很好。然而,当我尝试做类似的事情时,

x+1

我收到一条错误消息:

MismatchedTokenException:输入“+”不匹配,需要“\u001C”

我已经研究这个问题有一段时间了,但不明白为什么它适用于 *、- 和 /,但不适用于 +。我对它们都有完全相同的代码。

编辑:如果我重新排序并将减号放在加号之上,+ 符号现在可以使用,但 - 符号则不行。为什么antlr 会关心这样的事情的顺序呢?

I'm creating a grammar right now and I had to get rid of left recursion, and it seems work for everything except the addition operator.

Here is the related part of my grammar:

SUBTRACT: '-';
PLUS: '+';
DIVIDE: '/';
MULTIPLY: '*';

expr: 
      (
        IDENTIFIER 
        | INTEGER 
        | STRING 
        | TRUE 
        | FALSE
      )
      (
        PLUS expr 
        | SUBTRACT expr 
        | MULTIPLY expr 
        | DIVIDE expr 
        | LESS_THAN expr 
        | LESS_THAN_OR_EQUAL expr 
        | EQUALS expr
      )*
      ;

INTEGER: ('0'..'9')*;
IDENTIFIER: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')*;

Then when I try to do something like

x*1

It work's perfectly. However when I try to do something like

x+1

I get an error saying:

MismatchedTokenException: mismatched input '+' expecting '\u001C'

I've been at this for a while but don't get why it works with *, -, and /, but not +. I have the exact same code for all of them.

Edit: If I reorder it and put SUBTRACT above PLUS, the + symbol will now work but the - symbol won't. Why would antlr care about the order of stuff like that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

つ低調成傷 2024-10-27 08:59:08

我通过为删除左递归的最后部分制定新规则来修复它:

expr: 
      (
        IDENTIFIER 
        | INTEGER 
        | STRING 
        | TRUE 
        | FALSE
      ) lr*
      ;

lr:         PLUS expr 
        | SUBTRACT expr 
        | MULTIPLY expr 
        | DIVIDE expr 
        | LESS_THAN expr 
        | LESS_THAN_OR_EQUAL expr 
        | EQUALS expr;

I fixed it by making a new rule for the part at the end that I made from removing left recursion:

expr: 
      (
        IDENTIFIER 
        | INTEGER 
        | STRING 
        | TRUE 
        | FALSE
      ) lr*
      ;

lr:         PLUS expr 
        | SUBTRACT expr 
        | MULTIPLY expr 
        | DIVIDE expr 
        | LESS_THAN expr 
        | LESS_THAN_OR_EQUAL expr 
        | EQUALS expr;
落墨 2024-10-27 08:59:07

避免左递归(在表达式语法中)通常是这样完成的:

grammar Expr;

parse
  :  expr EOF
  ;

expr
  :  equalityExpr
  ;

equalityExpr
  :  relationalExpr (('==' | '!=') relationalExpr)*
  ;

relationalExpr
  :  additionExpr (('>=' | '<=' | '>' | '<') additionExpr)*
  ;

additionExpr
  :  multiplyExpr (('+'| '-') multiplyExpr)*
  ;

multiplyExpr
  :  atom (('*' | '/') atom)*
  ;

atom
  :  IDENTIFIER
  |  INTEGER
  |  STRING
  |  TRUE
  |  FALSE
  |  '(' expr ')'
  ;

// ... lexer rules ...

例如,输入 A+B+C 将被解析如下:

在此处输入图像描述

另请参阅此相关答案:ANTLR:有一个简单的例子吗?

Avoiding left recursion (in an expression grammar) is usually done like this:

grammar Expr;

parse
  :  expr EOF
  ;

expr
  :  equalityExpr
  ;

equalityExpr
  :  relationalExpr (('==' | '!=') relationalExpr)*
  ;

relationalExpr
  :  additionExpr (('>=' | '<=' | '>' | '<') additionExpr)*
  ;

additionExpr
  :  multiplyExpr (('+'| '-') multiplyExpr)*
  ;

multiplyExpr
  :  atom (('*' | '/') atom)*
  ;

atom
  :  IDENTIFIER
  |  INTEGER
  |  STRING
  |  TRUE
  |  FALSE
  |  '(' expr ')'
  ;

// ... lexer rules ...

For example, the input A+B+C would be parsed as follows:

enter image description here

Also see this related answer: ANTLR: Is there a simple example?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文