当其他字符首先需要时,ANTLR匹配字符?

时间:2012-01-09 21:39:52

标签: antlr antlr3

请参阅下面的语法。当我尝试解析时:

String s = "UNH+message refere+APERAK:D:97A:UN\n";

我收到以下错误:

line 1:34 mismatched character '\n' expecting 'H'
line 2:0 missing RDEL at '<EOF>'

这对我来说没有意义,因为它似乎在遇到\ n之前正在寻找UNH,这不符合'文件'规则。

    grammar Aperak;

    options {
      language = Java;
    }

    @header { package test.fixed.aperak; }
    @lexer::header { package test.fixed.aperak; }

    file returns [String result]: 'UNH' unh01 unh02 RDEL { $result = $unh01.text + " -- " + $unh02.text; };

    unh01 : FDEL optField;
    unh02 : FDEL unh02x1 unh02x2 unh02x3 unh02x4 (unh02x5)?;
    unh02x1 : optField;
    unh02x2 : SDEL optField;
    unh02x3 : SDEL optField;
    unh02x4 : SDEL optField;
    unh02x5 : SDEL optField;

    optField : AN*;

    RDEL : '\n';
    SDEL : ':';
    FDEL : '+';

    AN : 'a'..'z' | 'A'..'Z' | '0'..'9' | ' ';

2 个答案:

答案 0 :(得分:1)

我认为ANTLR真正混淆了涵盖UNH输入的两个重叠规则:

  • 单个令牌UNH
  • 包含AN类型的三个令牌的序列,文本为"U""N""H"

我认为您应该修改optFieldAN规则,将*移到词法分析器中,如下所示:

optField : AN?;

AN : ('a'..'z' | 'A'..'Z' | '0'..'9' | ' ')+;

答案 1 :(得分:1)

你的词霸非常像这样:

UNH  : 'UNH';
RDEL : '\n';
SDEL : ':';
FDEL : '+';
AN   : 'a'..'z' | 'A'..'Z' | '0'..'9' | ' ';

'UNH'规则中的文字file成为排在所有其他词法规则之上的词法规则。

当词法分析器现在偶然发现"UN"后跟"H"以外的其他内容时,会产生错误,因为词法分析器无处可回溯。如果您的AN规则匹配多个单个字符,则词法分析器可以遵循该规则,但由于它只匹配单个字符,因此词法分析器不会从"UN"回溯。

由于已建议的dasblinkenlight是正确的:AN应匹配1个或多个字符,然后optField可以匹配可选的AN。然而,他(或她)答案的另一部分并不完全正确:因此我的回答。