仍然在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。
答案 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:
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
,并且没有歧义(至少不在那个规则中)。