ANTLR将字符串的一部分视为关键字

时间:2010-11-29 15:57:13

标签: java antlr

我正在为自己学习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并抛出异常。

但是我不明白我做错了什么。任何帮助将不胜感激。

感谢。

1 个答案:

答案 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)*
  ;

// ...