我目前正在自学 ANTLR。首先,我决定编写最简单的语法。有带有指令的纯文本文件:
pid = something.pid
log = something.log
我写的语法是:
grammar TestGrammar;
options {
language = Java;
}
@header {
package test.antlr;
}
@lexer::header {
package test.antlr;
}
program
: directive+
;
directive
: pid
| log
;
pid
: PID EQ (WORD|POINT)+
;
log
: LOG EQ (WORD|POINT)+
;
WS: ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
PID
: 'pid'
;
LOG
: 'log'
;
EQ
: '='
;
POINT
: '.'
;
WORD
: ('a'..'z'|'A'..'Z'|'_')+
;
我觉得我在某处犯了一个错误,ANTLR 证明抛出了 MismatchedTokenException
。它将 something.pid 视为 指令
并抛出异常。
但是我不明白我做错了什么。任何帮助将不胜感激。
谢谢。
最佳答案
词法分析器是一个非常简单的对象:在不受解析器干扰的情况下,它对输入源进行标记化。所以,输入:
pid = something.pid
未标记为:
PID EQ WORD POINT WORD
但是作为:
PID EQ WORD POINT PID
这就是为什么你的规则:
pid
: PID EQ (WORD|POINT)+
;
匹配 "pid = something."
并将第二个 "pid"
留在 token 流中,期望 EQ
赋予它(因此异常(exception))。
一个可能的解决办法是做这样的事情:
pid
: PID EQ (word|POINT)+
;
log
: LOG EQ (word|POINT)+
;
word
: WORD
| PID
| LOG
;
或者通过做类似的事情:
pid
: PID EQ FULL_WORD
;
log
: LOG EQ FULL_WORD
;
// ...
FULL_WORD
: WORD (POINT WORD)*
;
// ...
关于java - ANTLR 将部分字符串视为关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4305473/