【问题标题】:ANTLR: simple example from ANTLRWorks wizard doesn't workANTLR:ANTLRWorks 向导中的简单示例不起作用
【发布时间】:2010-06-12 00:00:19
【问题描述】:

语法:

grammar test;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

start 
    :   STRING EOF;

是用向导生成的语法;我添加了规则“开始”。

在解释器中输入:

"abc"

控制台中的结果:

[19:09:54] Interpreting...
[19:09:54] problem matching token at 1:2 MismatchedTokenException(97!=34)
[19:09:54] problem matching token at 1:3 NoViableAltException('b'@[1:1: Tokens : ( WS | STRING );])
[19:09:54] problem matching token at 1:4 NoViableAltException('c'@[1:1: Tokens : ( WS | STRING );])
[19:09:54] problem matching token at 1:5 NoViableAltException(''@[()* loopback of 11:12: ( ESC_SEQ | ~ ( '\\' | '"' ) )*])

截图: http://habreffect.ru/files/200/4cac2487f/antlr.png

ANTLRWorks v1.4 也从控制台使用 ANTLR v3.2 进行了尝试,结果相同。

如果我输入“\nabc”而不是“abc”,它可以正常工作。 如果我在 STRING 规则中将 ESC_SEQ 放在右侧,则 "abc" 有效,但 "\nabc" 失败。

【问题讨论】:

  • 语法测试; WS : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;} ; STRING : '"' ( ESC_SEQ | ~('\\'|'"') )* '"' ; 片段 HEX_DIGIT : ('0'..'9'|'a'..'f'|'A' ..'F') ; 片段 ESC_SEQ : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | UNICODE_ESC |八进制_ESC ;片段 OCTAL_ESC : '\\' ('0'..'3') ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ;片段 UNICODE_ESC : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ;开始:字符串 EOF;
  • 我在解释器中输入“abc”。控制台:[19:09:44] 解释... [19:09:54] 解释... [19:09:54] 在 1:2 MismatchedTokenException(97!=34) [19:09: 54] 在 1:3 NoViableAltException('b'@[1:1: Tokens : ( WS | STRING );]) [19:09:54] 在 1:4 NoViableAltException('c'@ [1:1: Tokens : ( WS | STRING );]) [19:09:54] 1:5 NoViableAltException(''@[()* loopback of 11:12: ( ESC_SEQ | ~ ( ') \\' | '"' ) )*])
  • ANTLRWorks 版本:1.4。当我尝试从控制台使用 ANTLR 3.2 运行解释器时,也会发生同样的事情。
  • @Alexy,感谢您的澄清。
  • 这个错误在 ANTLRWorks 1.4.3 中再次出现。或者一开始就没有固定。

标签: antlr grammar antlr3 antlrworks


【解决方案1】:

这似乎是 ANTLRWorks 1.4 中的一个错误。您可以尝试使用 ATLRWorks 1.3(或更早版本),也许该版本可以正常工作(我只对 v1.4 进行了快速检查!)。

在控制台中,您的示例字符串("abc""\nabc")都被解析,没有任何问题。这是我的测试设备和相应的输出:

grammar test;

start 
  :  STRING {System.out.println("parsed :: "+$STRING.text);} EOF
  ;

WS  
  :  (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;}
  ;

STRING
  :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
  ;

fragment
HEX_DIGIT 
  :  ('0'..'9'|'a'..'f'|'A'..'F') 
  ;

fragment
ESC_SEQ
  :  '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
  |  UNICODE_ESC
  |  OCTAL_ESC
  ;

fragment
OCTAL_ESC
  :  '\\' ('0'..'3') ('0'..'7') ('0'..'7')
  |  '\\' ('0'..'7') ('0'..'7')
  |  '\\' ('0'..'7')
  ;

fragment
UNICODE_ESC
  :  '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
  ;

注意语法和你的一样,只是格式有点不同。

还有“主”类:

import org.antlr.runtime.*;

public class Demo {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream(args[0]);
        testLexer lexer = new testLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        testParser parser = new testParser(tokens);
        parser.start();
    }
}

现在从控制台创建解析器和词法分析器:

java -cp antlr-3.2.jar org.antlr.Tool test.g

编译所有.java源文件:

javac -cp antlr-3.2.jar *.java

并运行“主”类:

java -cp .:antlr-3.2.jar Demo \"\\nabc\"
// output:                                   parsed :: "\nabc"

java -cp .:antlr-3.2.jar Demo \"abc\"
// output:                                   parsed :: "abc"

(对于 Windows,将上述命令中的 : 替换为 ;

请注意,上面的命令行参数是在 Bash 上运行的示例,其中 "\ 需要转义:这可能在您的系统上有所不同。但正如您从输出中看到的那样:"\nabc""abc" 都被正确解析了。

ANTLRWorks 是编辑语法文件的好工具,但是(根据我的经验)它有很多这样有趣的错误。这就是为什么我只用它编辑语法并在控制台上生成、编译和测试文件,就像我向你展示的那样。

HTH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 2015-11-23
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多