Antlr3 语法在遇到英镑图表时生成解析错误

Antlr3 grammar generates parsering error on encountering the Pound char

Antlr-3 在遇到法语的 Pound char ("£") 时产生错误,这相当于 Hash "#[ 的 char =35=]" 的英文字符,连@#$[=三个特殊字符的Unicode值35=] 在 lexer/parser 规则中指定。

仅供参考: Pound char(法语)的 Unicode 值 = Hash char(英语)的 Unicode 值。

lexer/parser规则:

grammar SimpleCalc;

options
{
  k        = 8;
  language = Java;
  //filter   = true;
}
 
tokens {
    PLUS    = '+' ;
    MINUS   = '-' ;
    MULT    = '*' ;
    DIV = '/' ;
}
 
/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/
 
expr    : n1=NUMBER ( exp = ( PLUS | MINUS )  n2=NUMBER )* 
{
  if ($exp.text.equals("+"))
   System.out.println("Plus Result = " + $n1.text + $n2.text);
  else
   System.out.println("Minus Result = " + $n1.text + $n2.text);
}
;
 
/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/
 
NUMBER  : (DIGIT)+ ;
 
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;
 
fragment DIGIT  : '0'..'9' | '£' | ('\u0040' | '\u0023' | '\u0024');

文本文件也以 UTF-8 读取为:

    public static void main(String[] args) throws Exception
    {
        try
        {
            args = new String[1];
            args[0] = new String("antlr_test.txt");
            SimpleCalcLexer lex = new SimpleCalcLexer(new ANTLRFileStream(args[0], "UTF-8"));
            CommonTokenStream tokens = new CommonTokenStream(lex);
            
            SimpleCalcParser parser = new SimpleCalcParser(tokens);
            
            parser.expr();
            //System.out.println(tokens);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

输入文件只有 1 行:

 £3 + 4£
 

错误是:

antlr_test.txt line 1:1 no viable alternative at character '£'
antlr_test.txt line 1:7 no viable alternative at character '£'

我的方法有什么问题? 还是我错过了什么?

我无法重现您描述的内容。当我在没有修改的情况下测试你的语法时,我得到了一个 NumberFormatException,这是预期的,因为 Integer.parseInt("£3") 不能成功。

当我将您的嵌入式代码更改为:

{
  if ($exp.text.equals("+"))
   System.out.println("Result = " + (Integer.parseInt($n1.text.replaceAll("\D", "")) + Integer.parseInt($n2.text.replaceAll("\D", ""))));
  else
   System.out.println("Result = " + (Integer.parseInt($n1.text.replaceAll("\D", "")) - Integer.parseInt($n2.text.replaceAll("\D", ""))));
}

并重新生成词法分析器和解析器 类(您可能没有做过的事情)并重新运行驱动程序代码,我得到以下输出:

Result = 7

编辑

也许语法中的井号是问题所在?如果你尝试:

fragment DIGIT  : '0'..'9' | '\u00A3' | ('\u0040' | '\u0023' | '\u0024');

而不是:

fragment DIGIT  : '0'..'9' | '£' | ('\u0040' | '\u0023' | '\u0024');

?