【问题标题】:Parsing mixfix expression in antlr3在 antlr3 中解析 mixfix 表达式
【发布时间】:2017-06-10 12:59:21
【问题描述】:

我需要调整 ANTLR3 语法以支持 let 表达式。操作员需要非常弱地绑定。例如let x=3 in x + 1 读作let x=3 in (x+1) 而不是(let x=3 in x) + 1

不幸的是,我的候选语法仍然模棱两可。 有没有一种标准的方法可以使规则明确无误? (加上额外的( ) 就可以了。)

顺便说一句,它似乎适用于 ANTLR4 的盒子。但是,就我而言,这不是一个选择。

grammar Expr;

prog:   stat+ ;

stat:   expr NEWLINE
    |   ID '=' expr NEWLINE
    |   NEWLINE
    ;

expr:   sum ( ('*'|'/') sum )* ;

sum:    atom ( ('+'|'-') atom )* ;

atom:   INT
    |   ID
    |   '(' expr ')'
 // |   '(' let ')'
    |   let
    ;

let:    'let' ID '=' expr 'in' expr ;

ID  :   ('a' .. 'z')+ ;
INT :   ('0' ..'9')+ ;
NEWLINE: '\r'? '\n' ;
WS  :   ' ' { $channel = HIDDEN; };

【问题讨论】:

  • 应该也是3 * let x = 2 in x+13 * (let x=2 in x+1)一样。
  • 我试过设置options { greedy = true; },但可能位置不对?

标签: java parsing antlr antlr3


【解决方案1】:

没有问题。

输入的解析树

let x=3 in x + 1
3 * let x = 2 in x+1

【讨论】:

  • 我确实收到一条错误(或警告)消息:Decision can match input such as "{'*', '/'}" using multiple alternatives: 1, 2 等。显然,解析器恰好做了我想要它做的事情,但这似乎是巧合。它解决了对我有利的模棱两可的情况。幸运!
【解决方案2】:

正常的方法是为每个优先级设置一个不同的非终结符,像这样(请注意,您似乎将求和和产生的优先级颠倒了,所以我也修复了这个问题):

expr:   sum | let;

let:    'let' ID '=' expr 'in' expr ;

sum:    product ( ('+'|'-') prodcut)* ;

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

atom:   INT
    |   ID
    |   '(' expr ')'
    ;

【讨论】:

  • 感谢您的快速回复!我是不是误以为这个语法不接受3 + let x=2 in x
  • 是的。允许这样做会很奇怪,而且有点粗俗:你有一种特殊的原子,它只能出现在一种特殊的产品的末尾,它只能出现在一种特殊的和的末尾。
  • 也许很奇怪,但目标语言就是这样设计的。我曾尝试在更多地方添加提及 let 的“特殊”规则,但没有冲突。
  • 那么您可能希望使用模棱两可的语法。正常的默认规则是解决轮班减少冲突以支持轮班,这通常可以发挥作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多