如果在我的表达后期待词法分析器怎么办?

时间:2012-05-09 15:10:16

标签: java parsing antlr

仍然在Antlr工作,我搜索的是我在文档中找不到的东西。

这是一个可以检测到' not'字符串中的模式:

 factor : 'not'^ primary| primary;
 (and some other lines).

但是,如果我想在我的主要后检测表达式怎么办? 例如

B exists

如何在表达式的其余部分后定义解析器规则? 我通过类比尝试了这个,但直到现在还无法使用它。

 exists : primary 'exists'^ | primary;

根据我在表达中的位置,我得到了

line 1:44 extraneous input 'exists' expecting ')'

line 1:3 mismatched input 'exists' expecting ')'
line 1:22 missing EOF at ')'

错误

谢谢!

编辑:

我的语法和你的语法完全一样但是有一点。 这是我的代码:

// Aiming at parsing a complete BQS formed Query
grammar Logic;

options {
    backtrack=true;
    output=AST;
}

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

 parse  
    : expression EOF -> expression
    ; // ommit the EOF token

 expression
    : query
    ;       

 query  
    : term (OR^ term)*    // make `or` the root
    ;

 term   
    : factor (AND^ factor)*
    ;

 factor 
    : NOT^ primary 
    | primary
    ;


 primary // this one has to be completed (a lot)
    : atom (LIKE^ atom)* // right expressions have to be indicated
    | atom (EXISTS^)?
    ;

 atom   
    : ID 
    | '('! expression ')'! // omit both ( and )
    ;

/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/
// GENERAL OPERATORS: 
NOTLIKE :   'notlike'; // whitespaces have been removed
LIKE    :   'like';
EXISTS  :   'exists';

OR          :   'or';
AND         :   'and';
NOT         :   'not';

//ELEMENTS 
ID          :   (CHARACTER)+;   

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

所以问题显然来自这里。

我在这里遇到了严重的问题。 一旦删除了所有或之后,而且不是,我希望我的小学要么采用以下形式:

A like B

A exists

我的代码有什么问题?我认为这正是我的主要规则所说的?

我真的很想找到一种方法来调试自己,因为:

line 1:3 mismatched input 'like' expecting ')'  

真的不是自我解释

非常感谢你的帮助,我真的很难理解antlr文档网站:s。

1 个答案:

答案 0 :(得分:3)

我怀疑你在一个解析器规则中放错了EOF。您发布的规则似乎没有太大的错误:至少,不是可能导致您发布的错误的内容。

对于(可能的)未来问题(不仅仅是ANTLR问题),我强烈建议您发布一个“自包含”的语法(或示例代码)。换句话说:你发布一个人可以很容易的语法,而无需修改它(!),在他们自己的机器上运行,以便他们看到你所看到的。现在只是猜测你的其他规则是什么样的。

以下内容:

exists
 : atom (Exists^)?
 ;

就像魅力一样,你可以自己测试一下:

grammar T;

options {
  output=AST;
}

parse
 : expr EOF -> expr
 ;

expr
  :  orexp
  ;

orexp
  :  andexp (Or^ andexp)*
  ;

andexp
  :  not (And^ not)*
  ;

not
 : Not^ exists
 | exists
 ;

exists
 : atom (Exists^)?
 ;

atom
 : Num
 | Id
 | '(' expr ')' -> expr
 ;

Or     : 'or';
And    : 'and';
Exists : 'exists';
Not    : 'not';
Num    : '0'..'9'+;
Id     :  ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
Space  : ' ' {skip();};

输入:

(A or B) and (not C or D exists) or not E exists

生成以下AST:

enter image description here

修改

primary规则的备选方案1和备选方案2:

 primary
  : atom (LIKE^ atom)* // alternative 1
  | atom (EXISTS^)?    // alternative 2
  ;

匹配单个atom。这是解析器无法正确解析输入的原因(并且需要添加backtrack=true;,这应该避免!)。

我没有对它进行测试,但我非常确定如果从选项块中删除backtrack=true;并按以下方式重写primary,则可以正常运行:

primary
 : atom ( (LIKE^ atom)* // alternative 1
        | EXISTS^       // alternative 2
        )
 ;

现在备选方案1仅匹配单个atom,并且没有歧义(至少不在那个规则中)。