通常,我有一个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文件中出错了。而且我不知道该怎么做。