语法:
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;
这是用向导生成的语法;我添加了规则'start'。
口译员输入:
"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”失败。
答案 0 :(得分:2)
这似乎是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
并运行“main”类:
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