Parsing Antlr4语法-识别语法有困难
我正在使用Antlr4解析类似于DSL的布尔值 这是我的语法:Parsing Antlr4语法-识别语法有困难,parsing,antlr,antlr4,context-free-grammar,Parsing,Antlr,Antlr4,Context Free Grammar,我正在使用Antlr4解析类似于DSL的布尔值 这是我的语法: grammar filter; filter: overall EOF; overall : LPAREN overall RPAREN | category ; category : expression # InferenceCategory | category AND category # CategoryAndBlock | label COLON expressio
grammar filter;
filter: overall EOF;
overall
: LPAREN overall RPAREN
| category
;
category
: expression # InferenceCategory
| category AND category # CategoryAndBlock
| label COLON expression # CategoryBlock
| LPAREN category RPAREN # NestedCategory
;
expression
: NOT expression # NotExpr
| expression AND expression # AndExpr
| expression OR expression # OrExpr
| atom # AtomExpr
| LPAREN expression RPAREN # NestedExpression
;
label
: ALPHANUM
;
atom
: ALPHANUM
;
下面是要分析的示例输入字符串:
cat1:1或2和cat2:4
这种语法可以很好地处理这种输入;它生成了以下解析树,非常适合我的需要:
然而,DSL有一种奇怪的情况,当没有指定其他类别时,cat1标签是隐式的。这就是ExpressionCategory标记捕获的内容,稍后在我的代码中将此表达式作为一个类别处理
例如,与
1或2和cat2:4
我得到了预期的结果:
但是,在以下情况下:
cat2:4和1或2
我得到:
请注意,第二个块未标识为推断类别,而是第一个类别下的正常表达式。这是因为这里的语法将cat2:后面的4解析为一个普通表达式,而过去的所有内容都解析为一个普通表达式
有办法解决这个问题吗?我试过:
标记冒号表达式和类别*CategoryBlock
这不管用
及
类别和类别和类别
这是可行的,但非常粗糙,只在我有三个类别的特定情况下有效。任何其他标签,如NOT expression NotExpr,都不会对解析树产生影响。它们只是语义上的。它们将导致代码生成过程创建特定的签名,您可以在访问者或侦听器中覆盖这些签名 例如,这背后的基本原理是,不是只为表达式获得一个访问者覆盖,而是为每个可选标签获得多个访问者覆盖。这样,您就不必在对表达式进行操作之前检查表达式并确定它是什么类型。相反,例如,您将获得OrExpr的重写,一旦您在该重写代码中,您就知道您正在处理OR,OR标记的每一侧都有一个表达式
解析树很有用,但大部分语义只有在编写侦听器或访问者的代码时才会显现出来 您好,我知道在我与侦听器/访问者合作之前,替代标签仅具有语义。在本例中,我不确定如何在解析器级别唯一地标识这些隐式类别,因为它们在功能上是相同的。我目前的实现(我有点忽略了这个问题)一直有效,直到其中一个隐式类别出现在我的标签右侧:expression,在这种情况下,它被解释为一个表达式而不是一个类别,并成为另一个类别的子树,而不是主要问题的兄弟。