Parsing Antlr4语法-识别语法有困难

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

我正在使用Antlr4解析类似于DSL的布尔值

这是我的语法:

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,在这种情况下,它被解释为一个表达式而不是一个类别,并成为另一个类别的子树,而不是主要问题的兄弟。