2

希望这只是帮助我解决这个问题的适量信息。

给定以下 ANTLR3 语法

grammar mygrammar;

program : statement* | function*;

function : ID '(' args ')' '->' statement+ (','statement+) '.' ;    

args    : arg (',' arg)*;       

arg     : ID ('->' expression)?;

statement : assignment
          | number
          | string
          ;

assignment : ID '->' expression;    

string  : UNICODE_STRING;

number : HEX_NUMBER | INTEGER ( '.' INTEGER )?;


// ================================================================

HEX_NUMBER : '0x' HEX_DIGIT+;

INTEGER : DIGIT+;

fragment
DIGIT   :   ('0'..'9');

这是导致解析器出现问题的行。

my_function(x, y, z -> 42) -> 10001.

ANTLRWorks 将 10001 之后的最后一个 .以红色突出显示为以下错误的问题。

我怎样才能让这个停止投掷org.antlr.runtime.EarlyExitException

我确信这是因为我的number解析器规则和尝试使用.EOL 分隔符之间存在一些歧义。

4

2 回答 2

3

还有另一个歧义也需要修正。改变:

program : statement* | function*;

进入:

program  : (statement | function)*;

(虽然 2 不等价,但我猜你想要后者)

在您的function规则中,您现在定义了至少 2statement秒:

function : ID '(' args ')' '->' statement (','statement)+ '.' ; 

虽然我猜你真的想要至少一个:

function : ID '(' args ')' '->' statement (','statement)* '.' ; 

现在,您真正的问题:由于您在解析器规则中构建浮点数,因此从输入的末尾,10001.解析器尝试构建number它的 a ,而您希望它匹配 anINTEGER然后 a .,正如您自己已经说过的那样在你的 OP 中。

要解决此问题,您需要给解析器一些额外的前瞻性,以“看到”超越这种歧义。(INTEGER '.' INTEGER)=>通过在实际匹配所述输入之前添加谓词来做到这一点:

number
  :  HEX_NUMBER 
  |  (INTEGER '.' INTEGER)=> INTEGER '.' INTEGER 
  | INTEGER
  ;

现在您的输入将生成以下解析树:

在此处输入图像描述

于 2011-11-11T14:03:06.863 回答
1

也许无关,但我很好奇:

function : ID '(' args ')' '->' statement+ (','statement+) '.' ;

这应该是:

function : ID '(' args ')' '->' statement (',' statement)* '.' ;

我认为第一个在函数定义中需要一个逗号,但第二个需要一个逗号作为语句分隔符。

另外,args允许的规则z -> 42是否正确?

于 2011-11-11T00:58:31.757 回答