我正在为自己学习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
。它将某些内容。 pid 视为directive
并抛出异常。
但是我不明白我做错了什么。任何帮助将不胜感激。
感谢。
答案 0 :(得分:2)
词法分析器是一个非常简单的对象:没有来自解析器的干扰,它会对输入源进行标记。所以,输入:
pid = something.pid
不标记为:
PID EQ WORD POINT WORD
但是:
PID EQ WORD POINT PID
这就是你的规则:
pid
: PID EQ (WORD|POINT)+
;
匹配"pid = something."
并将第二个"pid"
留在令牌流中,期望EQ
使用它(因此例外)。
可能的解决方法是做这样的事情:
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)*
;
// ...