0

我尝试使用 ANTLR 编写具有以下细节的语法。

它可以解析如下标识符:

foo > bar > 67

其中 foo > bar 是标识符,因为 if > 后跟一个字母,它包含标识符,否则它是大于运算符。

我应该解析类似的东西

((a = 1) AND (b = 2)) OR (c = 3)

其中 ( ) 是必要的。

我对这个主题和 ANTLR 真的很陌生,希望有人能提供帮助。

我目前有这个语法

 grammar testgrammer;

start   :   statement EOF;

statement
    :   operation  (AND operation)*;

operation
    :   '(' ID OPERATOR INT ')';

AND :   'AND';

OPERATOR:   '=' | '>';

ID  
  :  ('a'..'z'| 'A'..'Z')+ (WS '>' WS ('a'..'z' | 'A'..'Z')+)?
  ;

WS  
  :  ' '+ {skip();}
  ;

INT :   '0'..'9'+
    ;

但我不知道如何在 id 中的 > 和作为运算符的 > 之间切换。

4

1 回答 1

1

首先,这是一件令人困惑的事情:既是"foo > bar"标识符又"foo > 67"是表达式。

由于您允许在此类标识符中使用空格,因此您的词法分析器将像输入一样绊倒,"foo > 67"因为"foo > "它会尝试使用一个字母但看到一个数字。并且词法分析器不会回溯,"foo > "因为没有可以从中创建单个标记(请注意,词法分析器永远不会放弃它消耗的字符!)。

为了处理这个问题,您必须确保词法分析器可以匹配" > "后跟一些字母。您可以使用句法谓词(( ... )=>部分)来做到这一点:

Id
 : IdPart ((Spaces? '>' Spaces? IdPart)=> Spaces? '>' Spaces? IdPart)*
 ;

SpaceChars
 : (Spaces | '\r' | '\n') {skip();}
 ;

fragment Digit  : '0'..'9';
fragment Letter : 'a'..'z' | 'A'..'Z';
fragment Spaces : (' ' | '\t')+;
fragment IdPart : Letter (Letter | Digit)*;

请注意,您不能使用其中的规则SpaceCharsId因为该规则会调用该skip()方法。

于 2012-06-14T19:45:22.053 回答