2012-01-09 67 views
1

请参阅下面的语法。当我尝试解析:当其他字符需要优先时ANTLR匹配字符?

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>' 

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

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' | ' '; 

回答

1

你词法真的是这样的:

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

file规则的字面'UNH'成为词法分析规则放在所有其他词法分析规则之上。

当词法分析器现在发现"UN"后面跟着"H"以外的东西时,它会产生一个错误,因为词法分析器无处可返回。如果您的AN规则匹配了多个单个字符,则词法分析器可以遵循该规则,但由于它只匹配单个字符,词法分析器不会从"UN"回溯。

由于dasblinkenlight已经提示是正确的:AN应该匹配1个或多个字符,然后optField可以匹配可选的AN。他(或她)的答案的另一部分不太正确,因此我的答案。

1

我认为ANTLR得到具有两个重叠的规则覆盖UNH输入真正困惑:

  • 单个令牌UNH,或
  • AN类型的三个令牌的序列,与文本"U""N",和"H"

我薄K优应该修改optFieldAN规则为*进入词法分析器,像这样:

optField : AN?; 

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

你的修正是正确的,但答案并不完全正确:词法分析器不会因为三个标记而感到困惑:这些标记(“U”,“N”,“H”)将会不会被创建。在尝试从输入'UNx'(其中'“x”是除“H”之外的任何其他输入)创建一个'UNH'标记后,词法分析器无处可回,因为'AN'匹配单个字符。 – 2012-01-10 08:43:00

+0

@BartKiers我没有说三个标记*会被创建,只是有一个规则可以用来将字符串UNH解释为三个标记的序列。对我来说,“词法分析器无处可回”是一种明智的方式来说“词法分析器变得困惑”:) – dasblinkenlight 2012-01-10 12:20:48

+0

你说:*“一个由三个”AN“类型的标记组成的序列,其中带有”U“ ,''N“',和'”H“'”* ...或许你的意思是我刚才所说的,但措辞表明了我之前评论的内容。 – 2012-01-10 12:42:42