首页 > 解决方案 > 如何解决“以下规则集相互左递归”ANTLR错误

问题描述

以下几组规则是相互左递归的 [valeurBooleene, valeur]

我知道 ANTLR 可以很好地处理左递归规则,但只能在一个规则中,而不是在规则之间。

我必须重写我的规则来解决相互左递归的问题,但我不知道如何......

grammar minimal;

constante:
   bool  = BOOLEAN
 | intgr = INTEGER
;
valeurBooleene:
   '(' val = valeurBooleene ')'
 | bool       = BOOLEAN
 | 'non'  not = valeur
 | leftValue = valeur '=' rightValue = valeur
;
valeur:
   '(' val = valeur ')'
 | cst          = constante
 | booleanValue = valeurBooleene
 | '|' absolute = valeur '|'
 | '-' opposite = valeur
;
condition:
   '(' cond = condition ')'
 | bool = valeurBooleene
;
si:
   'Si' cond = condition 'alors' ( thenActions += action )+
      ( 'sinon' ( elseActions += action )+ )?
;
system:
   ( actions += action )+
   EOF
;
action:
   ifClause = si
;
BOOLEAN:
   'false'
 | 'true'
 | 'faux'
 | 'vrai'
;
INTEGER:
   [0-9]+
;
WS:
   [ \n\t\r]+ -> skip
;

标签: antlr4grammarll

解决方案


最后,我遵循sepp2k提供的建议,如下所示:

grammar minimal;

value:
   '(' val = value ')'     # Parenthesis
   
 | b = BOOLEAN             # Boolean
 | 'non' not = value       # Boolean
 | l = value '=' r = value # Boolean
 
 | i = INTEGER             # Numeric
 | '|' abs = value '|'     # Numeric
 | '-' opposite = value    # Numeric
;
condition:
   '(' condition ')'
 | cond = value
;
ifStmnt:
   'IF' condition 'THEN' ( actionsThen += action )+
      ( 'ELSE' ( actionsElse += action )+ )?
;
system:
   ( actions += action )+
   EOF
;
print:
   'print' val = value 
;
action:
   ifs = ifStmnt
 | pr  = print
;
BOOLEAN:
   'false'
 | 'true'
;
INTEGER:
   [0-9]+
;
WS:
   [ \n\t\r]+ -> skip
;

标签创建扩展 ValueContext 的类,我像这样使用它们:

package com.thalesgroup.dms.stimulus.factories;

import minimal.minimalParser.BooleanContext;
import minimal.minimalParser.ConditionContext;
import minimal.minimalParser.NumericContext;
import minimal.minimalParser.ParenthesisContext;
import minimal.minimalParser.ValueContext;

public class Sample {

   void analyze( ValueContext ctxt ) {
      if( ctxt instanceof ParenthesisContext ) {
         analyze(((ParenthesisContext)ctxt).val );
      }
      else if( ctxt instanceof BooleanContext ) {
         final BooleanContext bc = (BooleanContext)ctxt;
         analyze( bc );
      }
      else if( ctxt instanceof NumericContext ) {
         final NumericContext nc = (NumericContext)ctxt;
         analyze( nc );
      }
   }

   void analyze( ConditionContext ctxt ) {
      if( ctxt.cond instanceof BooleanContext ) {
         final BooleanContext boolCtxt = (BooleanContext)ctxt.cond;
         // build a condition from a BooleanContext
         analyze( boolCtxt );
      }
      else {
         throw new IllegalStateException();
      }
   }

   void analyze( BooleanContext ctxt ) {
      if( ctxt.b != null ) {
         final String literal = ctxt.b.getText();
         if( literal.equals( "true" )) {
            // deal with a boolean literal 'true'
         }
         else if( literal.equals( "false" )) {
            // deal with a boolean literal 'false'
         }
      }
      else if( ctxt.not != null ) {
         final BooleanContext bCtxt = (BooleanContext)ctxt.not;
         // deal with a 'not' operation
      }
      else if( ctxt.l != null ) {
         final ValueContext left  = ctxt.l;
         final ValueContext right = ctxt.r;
         // deal with 'equals'
      }
      else {
         // ???
      }
   }

   void analyze( NumericContext ctxt ) {
      if( ctxt.abs != null ) {
         // deal with abs( x )
      }
      else if( ctxt.opposite != null ) {
         // deal with - x
      }
      else if( ctxt.i != null ) {
         // deal with literal integer
      }
   }
}

推荐阅读