Java 取“的lexer;不是";但不是",;不象;

Java 取“的lexer;不是";但不是",;不象;,java,parsing,antlr,grammar,lexer,Java,Parsing,Antlr,Grammar,Lexer,我需要一个小技巧来让解析器完全工作。 我使用antlr解析布尔查询 查询由元素组成,这些元素通过and、OR和NOT链接在一起 所以我可以吃一些像: "(P or not Q or R) or (( not A and B) or C)" 事实是,一个元素可以很长,通常的形式是: a an_operator b 例如: "New-York matches NY" 技巧,其中一个an_运算符是“不喜欢” 所以我想修改我的lexer,以便not检查后面是否没有like,以避免解析包含“not

我需要一个小技巧来让解析器完全工作。 我使用antlr解析布尔查询

查询由元素组成,这些元素通过and、OR和NOT链接在一起

所以我可以吃一些像:

"(P or not Q or R) or (( not A  and B) or C)"
事实是,一个元素可以很长,通常的形式是:

a an_operator b
例如:

"New-York matches NY"
技巧,其中一个an_运算符是“不喜欢”

所以我想修改我的lexer,以便not检查后面是否没有like,以避免解析包含“notlike”操作符的元素

我现在的语法是:

// save it in a file called Logic.g
grammar Logic;

options {
  output=AST;
}

// parser/production rules start with a lower case letter
parse
  :  expression EOF!    // omit the EOF token
  ;

expression
  :  orexp
  ;

orexp
  :  andexp ('or'^ andexp)*    // make `or` the root
  ;

andexp
  :  notexp ('and'^ notexp)*      // make `and` the root
  ;

notexp
  :  'not'^ atom    // make `not` the root
  |  atom
  ;

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

// lexer/terminal rules start with an upper case letter
ID    : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
任何帮助都将不胜感激。
谢谢

这里有一个可能的解决方案:

grammar Logic;

options {
  output=AST;
}

tokens {
  NOT_LIKE;
}

parse
  :  expression EOF!
  ;

expression
  :  orexp
  ;

orexp
  :  andexp (Or^ andexp)*
  ;

andexp
  :  fuzzyexp (And^ fuzzyexp)*
  ;

fuzzyexp
  :  (notexp -> notexp) ( Matches e=notexp  -> ^(Matches $fuzzyexp $e)
                        | Not Like e=notexp -> ^(NOT_LIKE $fuzzyexp $e)
                        | Like e=notexp     -> ^(Like $fuzzyexp $e)
                        )?
  ;

notexp
  :  Not^ atom
  |  atom
  ;

atom
  :  ID
  |  '('! expression ')'!
  ;

And     : 'and';
Or      : 'or';
Not     : 'not';
Like    : 'like';
Matches : 'matches';
ID      : ('a'..'z' | 'A'..'Z')+;
Space   : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
这将把输入的
“A不象B或C,象D和(E或不是F)和G匹配H”
解析为以下AST:


我说的是莱克斯和雅克语,不是安特尔语。lex中的典型解决方案是显式识别关键字和运算符;解析器规范没有。在Antlr中,你不能编写像“'notlike'^atom'”这样的产品吗?@davidgorline,我不会让
not like
not
那样的一元运算符。
not
通常否定布尔表达式,而
not-like
比较两个值(表达式的左侧和右侧)。另外,当中间有更多的空格时,或者当lexer遇到输入时,比如
'not like'
'not lik'
(这将导致lexer跳闸,就像gnu lex一样,我相信,但我不会说得太流利:)非常感谢,很高兴看到更多的g代码:)。不过,我确实在寻找一种完全抛弃“不喜欢”的方法,因为我使用了另一种解析技术。我会搜索“a不喜欢B小学”和“C喜欢D小学”。在中只应处理OR、NOT和括号fact@jlengrand,我不知道你所说的“完全抛弃”是什么意思。是否要跳过这些令牌?再详细一点会有帮助的。请不要使用评论框进行解释:改为编辑原始问题。更新了我的答案。希望如此helps@jlengrand,不,我还不清楚。你说你“不喜欢”不应该被处理,但那是什么意思?从流中跳过?标记为其他东西(然后呢?)?我发布了一个示例,说明了根据示例语法生成的解析器如何为输入构建AST
“A与B或C不相似,D与(E或非F),G与H匹配”
。现在,您可以指出您正在尝试创建的AST吗?不是用文字,而是像我发布的真实图像(当然可以是ASCII图像)。嗨。抱歉耽搁了。我一直在重新考虑我的方法,我认为花一些时间真正学习Antlr的工作方式比仅仅为了快速修复而运行更有用。我将尝试只使用一个解析器而不是两个,因此您的答案非常适合这个问题。非常感谢你