如何在规则中获取所有逻辑运算符标记

时间:2018-04-26 02:56:28

标签: java parsing antlr antlr4

我在规则中获取所有运营商令牌时遇到问题。例如,如果我的输入是(状态=失败)和(states1 =名义)或(states2 =名义),那么我想得到“和”/“或” 。我已经有一个语法可以解析我的输入,但'和'以及'或'这样的词是我语法中的关键词。因此它们可以显示在解析树中,但它们与规则不匹配。

enter image description here

我想通过Listener方法完成它,但我不知道如何获取这些令牌。 我的lexer文件:

lexer grammar TransitionLexer;

BOOLEAN: 'true' | 'false';
IF: 'if';
THEN: 'then';
ELSE: 'else';

NAME: (ALPHA | CHINESE | '_')(ALPHA | CHINESE | '_'|DIGIT)*;

ALPHA: [a-zA-Z];
CHINESE: [\u4e00-\u9fa5];

NUMBER: INT | REAL;
INT: DIGIT+
    |'(-'DIGIT+')';
REAL: DIGIT+ ('.' DIGIT+)?
    | '(-' DIGIT+ ('.' DIGIT+)? ')';
fragment DIGIT: [0-9];

OPCOMPARE: '='|'>='|'<='|'!='|'>'|'<';
WS: [ \t\n\r]+ ->skip;
SL_COMMENT:  '/*' .*? '*/' ->skip;

我的语法文件:

grammar TransitionCondition;
import TransitionLexer;
@parser::header{
    import java.util.*;
}
@parser:: members{
    private List<String> keywords = new ArrayList<String>();

    public boolean isKeyWord(){
        return keywords.contains(getCurrentToken().getText());
    }

    public List<String> getKeywords(){
        return keywords;
    }
}

condition : stat+ EOF;
stat : expr;

expr: pair (('and' | 'or') pair)*
    | '(' pair ')';

pair: '(' var OPCOMPARE value ')'   # keyValuePair
      | booleanExpr # booleanPair
      | BOOLEAN         # plainBooleanPair
      ;

var: localStates    # localVar
     | globalStates # globalVar
     | connector        # connectorVar
     ;
localStates: NAME;
globalStates: 'Top' ('.' brick)+ '.' NAME;
connector: brick '.' NAME;

value: {isKeyWord()}? userDefinedValue
         |basicValue
         ;

userDefinedValue: NAME;
basicValue: arithmeticExpr | booleanExpr;

booleanExpr: booleanExpr op=('and' | 'or') booleanExpr
                       | BOOLEAN
                       | relationExpr
                       | 'not' booleanExpr
                       | '(' booleanExpr ')'
                       ;
relationExpr: arithmeticExpr
                      | arithmeticExpr OPCOMPARE arithmeticExpr
                      ;
arithmeticExpr: arithmeticExpr op=('*'|'/') arithmeticExpr
                           | arithmeticExpr op=('+'|'-') arithmeticExpr
                           | 'min' '(' arithmeticExpr (',' arithmeticExpr)* ')'
                           | 'max' '(' arithmeticExpr (',' arithmeticExpr)* ')'
                           | globalStates
                           | connector
                           | localStates
                           | NUMBER
                           | '(' arithmeticExpr ')'
                           ;
brick: NAME;

我的输入文件t.expr,内容为:(states = failed) and (states1 = nominal) or (states2 = nominal)

  

我使用'grun'在命令行中获取树。

1 个答案:

答案 0 :(得分:1)

如果您label解析器规则为expr

expr
 : pair (operators+=('and' | 'or') pair)* #logicalExpr
 | '(' pair ')'                           #parensExpr
 ;

您的(生成的)侦听器类将包含以下方法:

void enter_logicalExpr(TransitionConditionParser.LogicalExprContext ctx);

void enter_parensExpr(TransitionConditionParser.ParensExprContext ctx);

enter_logicalExpr内,您可以从上下文中and找到or / java.util.List个令牌:ctx.operators