1

我正在使用 Java 目标。我有以下简单的语法:

    grammmar example;

    alpha :
            alpha 'something'
          | 'otherthing' ;

现在我希望我的解析器在进入规则 alpha 时Hello World for something打印。Hello World for otherthing所以我想通过以下方式修改我的语法:

    grammmar example;

    alpha :
            {System.out.println("Hello World for something");}
            alpha 'something'
          | {System.out.println("Hello World for otherthing");}
            'otherthing' ;

但这会导致解析器抛出规则项相互左递归的错误。此错误是由于在左递归替代方案中使用了任何 {...} 语句。

我还有什么其他选择,因为这似乎是一个错误/可以在 ANTLR4 中改进?

4

1 回答 1

2

ANTLR 4 只支持直接左递归。你在这里所做的是隐藏了一个动作后的左递归。

最简单的解决方案是为您的语法实现一个侦听器,并将println语句添加到您的enterAlpha.

这是没有动作的语法代码:

alpha
  : alpha 'something'
  | 'otherthing'
  ;

这是带有操作代码的侦听器方法:

@Override
public void enterAlpha(AlphaContext ctx) {
  if (ctx.alpha() != null) {
    System.out.println("Hello World for something");
  } else {
    System.out.println("Hello World for otherthing");
  }
}

该代码中使用的条件可能看起来很奇怪,但由于语法的编写方式,没有其他方法可以确定在代码中采用了哪个替代方案alpha。这种情况可以(并且可能应该)通过几种方式来解决,以提高代码的清晰度。以下提示可以单独使用或组合使用。

something选项 1:为andotherthing关键字添加显式词法分析器规则。

alpha
  : alpha Something
  | Otherthing
  ;

Something : 'something';
Otherthing : 'otherthing';

通过在规则中引用Something和,ANTLR 将生成访问器方法,为您提供对为解析树中的标记创建的实例的直接访问。OtherthingalphaAlphaContextTerminalNode

@Override
public void enterAlpha(AlphaContext ctx) {
  if (ctx.Something() != null) {
    System.out.println("Hello World for something");
  } else if (ctx.Otherthing() != null) {
    System.out.println("Hello World for otherthing");
  } else {
    assert ctx.exception != null; // only reachable if a parse error occurred
  }
}

选项 2:标记alpha规则的外部备选方案。

这将导致 ANTLR 为每个备选方案生成单独的上下文类,这也允许您分别实现侦听器/访问器功能。

alpha
  : alpha 'something'  # mySomething
  | 'otherthing'       # myOtherthing
  ;

监听器现在可能看起来像这样:

@Override
public void enterMySomething(MySomethingContext ctx) {
  System.out.println("Hello World for something");
}

@Override
public void enterMyOtherthing(MyOtherthingContext ctx) {
  System.out.println("Hello World for otherthing");
}
于 2013-07-20T01:27:07.397 回答