Как получить весь токен логического оператора в правиле - PullRequest
0 голосов
/ 26 апреля 2018

У меня проблема с получением всех токенов оператора в правиле.Например, если мой ввод (состояний = сбой) и (состояний1 = номинал) или (состояний2 = номинал) , то я хочу получить "и" / "или" .У меня уже есть грамматика, которая может анализировать мой ввод, но такие слова как 'и' и 'или' являются ключевыми словами в моей грамматике.Чтобы они могли отображаться в дереве разбора, но они не соответствовали правилу.

enter image description here

Я хочу закончить это методом Listener, но я не знаю, как получить эти токены. Мой файл лексера:

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 голосов
/ 26 апреля 2018

Если вы метка ваше правило синтаксического анализатора expr:

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

ваш (сгенерированный) класс слушателя будет содержать следующие методы:

void enter_logicalExpr(TransitionConditionParser.LogicalExprContext ctx);

void enter_parensExpr(TransitionConditionParser.ParensExprContext ctx);

Inside enter_logicalExpr вы можете найти токены and / or в java.util.List из контекста: ctx.operators.

...