ANTLR:区分一元和二元运算符的问题(例如减号)

发布于 2024-09-29 00:51:32 字数 310 浏览 5 评论 0原文

我正在使用 ANTLR (3.2) 来解析一些相当简单的语法。不幸的是,我遇到了一个小问题。采用以下规则:

exp
 : NUM
 | '(' expression OPERATOR expression ')' -> expression+
 | '(' (MINUS | '!') expression ')' -> expression
 ;

OPERATOR 包含与 MINUS 定义相同的减号 ('-')。现在ANTLR似乎无法处理这两个规则。如果我删除其中任何一个,一切都会正常。

有人有想法吗?

i'm using ANTLR (3.2) to parse some rather simple grammar. Unfortunately, I came across a little problem. Take the follwoing rule:

exp
 : NUM
 | '(' expression OPERATOR expression ')' -> expression+
 | '(' (MINUS | '!') expression ')' -> expression
 ;

OPERATOR contains the same minus sign ('-') as is defined with MINUS. Now ANTLR seems to be unable to deal with these two rules. If I remove either one, everything works fine.

Anyone ideas?

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

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

发布评论

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

评论(1

孤者何惧 2024-10-06 00:51:32

使一元表达式成为具有最高优先级的表达式。我还会对一元 - 使用不同的标记,以便更好地区分减号。演示:

grammar Exp;

options { 
  output=AST;
}

tokens {
  UNARY;
}

parse
  :  exp EOF
  ;

exp
  :  additionExp
  ;

additionExp
  :  multiplyExp ('+'^ multiplyExp | '-'^ multiplyExp)*
  ;

multiplyExp
  :  unaryExp ('*'^ unaryExp | '/'^ unaryExp)* 
  ;

unaryExp
  :  '-' atom -> ^(UNARY atom)
  |  '!' atom -> ^('!' atom)
  |  atom
  ;

atom
  :  '(' exp ')' -> exp
  |  Number      -> Number
  ;

Number : ('0'..'9')+ ('.' ('0'..'9')+)? ;

Spaces : (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;} ;

对源代码的快速测试:

3 * -4 + 7 / 6 * -(3 + -7 * (4 + !2))

生成以下 AST:

alt text

Make the unary expression the one with the highest precedence. I'd also use a different token for the unary - to make the distinction between the minus better. A demo:

grammar Exp;

options { 
  output=AST;
}

tokens {
  UNARY;
}

parse
  :  exp EOF
  ;

exp
  :  additionExp
  ;

additionExp
  :  multiplyExp ('+'^ multiplyExp | '-'^ multiplyExp)*
  ;

multiplyExp
  :  unaryExp ('*'^ unaryExp | '/'^ unaryExp)* 
  ;

unaryExp
  :  '-' atom -> ^(UNARY atom)
  |  '!' atom -> ^('!' atom)
  |  atom
  ;

atom
  :  '(' exp ')' -> exp
  |  Number      -> Number
  ;

Number : ('0'..'9')+ ('.' ('0'..'9')+)? ;

Spaces : (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;} ;

A quick test with the source:

3 * -4 + 7 / 6 * -(3 + -7 * (4 + !2))

produced the following AST:

alt text

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