如何动态地将令牌注入lexer规则

时间:2018-04-24 02:46:28

标签: java parsing antlr antlr4

通常,我有一个lexer文件和一个解析器文件,我将lexer文件导入到解析器文件中。 我的问题是我想在lexer文件中保留一个名为userdefinedValue的规则,它应该是一组String。但是它的价值只能在我运行我的程序时才能确定。
那么如何动态地将String注入到lexer中的userdefinedValue?

这是我的词法分析员:

lexer grammar TransitionLexer;

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

UserdefinedValue: ;
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;

condition : stat+ EOF;
stat : single | expr;

single: pair EOF;

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

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

var: localStates
     | globalStates
     | connector
     ;
localStates: NAME;
globalStates: 'Top' ('.' brick)+ '.' NAME;
connector: brick '.' NAME;

value: UserdefinedValue | basicValue;

basicValue: booleanExpr | arithmeticExpr;

booleanExpr: booleanExpr op=('and' | 'or') booleanExpr
                       | BOOLEAN
                       | relationExpr
                       | 'not' booleanExpr
                       | '(' booleanExpr ')'
                       ;
relationExpr: arithmeticExpr
                      | arithmeticExpr OPCOMPARE arithmeticExpr
                      ;
arithmeticExpr: arithmeticExpr op=('*'|'/') arithmeticExpr
                           | arithmeticExpr op=('+'|'-') arithmeticExpr
                           | NAME
                           | NUMBER
                           | '(' arithmeticExpr ')'
                           ;

brick: NAME;

我尝试了什么

如您所见,词法分析器中的UserdefinedValue即为空。我读了一些答案 其他问题。例如Dynamically create lexer rule

所以我改变我的解析器文件部分是这样的:

grammar TransitionCondition;
import TransitionLexer;
@lexer :: header{
    import java.util.*;
}
@lexer :: members{
    Set<String> keywords;
    public TransitionConditionLexer(CharStream input, Set<String> keywords) {
         super(input);
         this.keywords = keywords;
     }
}

condition : stat+ EOF;
stat : single | expr;

single: pair EOF;

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

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

var: localStates
     | globalStates
     | connector
     ;
localStates: NAME;
globalStates: 'Top' ('.' brick)+ '.' NAME;
connector: brick '.' NAME;

value:  basicValue {if(keywords.contains($text)) type=Keywords;};
fragment Keywords : ;

但它在java文件中出错了。而且我不知道该怎么做。

0 个答案:

没有答案