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