1

虽然我对有关 Antlr 语法的大量问题感到有些欣慰(不仅仅是我试图剃掉这个牦牛形状的东西),但我还没有找到一个可以帮助解决我的问题的问题/答案。

我将 Antlr3.3 与混合令牌/解析器词法分析器一起使用。

我正在使用 gUnit 来帮助证明语法和一些 jUnit 测试;这就是乐趣的开始。

我有一个要解析的简单配置文件:

identifier foobar {
port=8080
stub plusone.google.com {
        status-code = 206
        header = []
        body = []
  }
 }

我在解析“标识符”(本例中为 foobar)时遇到问题: 我想允许的有效名称是:

foobar
foo-bar
foo_bar
foobar2
foo-bar2
foo_bar2
3foobar
_foo-bar3

依此类推,因此有效的名称可以使用字符'a..z'|'A..Z', '0..9' '_' and '-'

我得出的语法是这样的(注意这不是完整的语法,只是与这个问题相关的部分):

fragment HYPHEN : '-' ;

fragment UNDERSCORE : '_' ;

fragment DIGIT  : '0'..'9' ;

fragment LETTER : 'a'..'z' |'A'..'Z' ;

fragment NUMBER : DIGIT+ ;

fragment WORD : LETTER+  ;

IDENTIFIER : DIGIT | LETTER (LETTER | DIGIT | HYPHEN | UNDERSCORE)*;

和相应的 gUnit 测试

IDENTIFIER:
"foobar" OK
"foo_bar" OK
"foo-bar" OK
"foobar1" OK
"foobar12" OK
"foo-bar2" OK
"foo_bar2" OK
"foo-bar-2" OK
"foo-bar_2" OK
"5foobar" OK
"f_2-a" OK
"aA0_" OK
// no "funny chars"
"foo@bar" FAIL
// not with whitepsace
"foo bar" FAIL

运行 gUnit 测试仅对“5foobar”失败。我已经设法解析了困难的东西,但解析标识符这一看似简单的任务却打败了我。

谁能指出我哪里出错了?我怎样才能匹配而不贪心?

提前谢谢了。

- 更新 -

我根据 Barts 的回答将语法更改为:

IDENTIFIER : ('0'..'9'| 'a'..'z'|'A'..'Z' | '_'|'-') ('_'|'-'|'a'..'z'|'A'..'Z'|'0'..'9')* ;

这修复了失败的 gUnit 测试,但破坏了一个无关的 jUnit 测试,该测试测试“端口”参数。以下语法处理上面配置片段的“port=8080”元素:

configurationStatement[MiddlemanConfiguration config]
        :   PORT EQ port=NUMBER {
config.setConfigurationPort(Integer.parseInt(port.getText())); }
            |   def=proxyDefinition { config.add(def); }
;

我得到的信息是:

mismatched input '8080' expecting NUMBER

其中 NUMBER 定义为NUMBER : ('0'..'9')+ ;

将 NUMBER 的规则移到 IDENTIFIER 块上方,解决了这个问题。

4

1 回答 1

1
IDENTIFIER : DIGIT | LETTER (LETTER | DIGIT | HYPHEN | UNDERSCORE)*;

相当于:

IDENTIFIER 
 : DIGIT 
 | LETTER (LETTER | DIGIT | HYPHEN | UNDERSCORE)*
 ;

因此, anIDENTIFIER是一个单一的DIGIT,或者以 a 开头,LETTER后跟(LETTER | DIGIT | HYPHEN | UNDERSCORE)*

你可能的意思是:

IDENTIFIER 
 : (DIGIT | LETTER | UNDERSCORE) (LETTER | DIGIT | HYPHEN | UNDERSCORE)*
 ;

但是,这也允许3---3作为有效IDENTIFIER的,对吗?

于 2012-07-09T14:44:09.283 回答