我有一个令牌OR:'或';我用它来评估一个布尔表达式(a == b OR a == c)我有另一个规则来解析状态缩写,它在char列表AZ,AK,OR,GA ...
我发现的是,antlr在状态列表中存在错误,或者应该是or
令牌,而不是
stateName
: CHAR CHAR (','|EOF) ->^(STATE CHAR+)
;
我将如何解决这种模棱两可的问题?
这里是我试图解析的一些规则
这是我正在使用的gramar
grammar PointFieldRule;
options
{
//language = 'CSharp3';
output=AST;
ASTLabelType=CommonTree;
}
tokens{
STATE;
}
rule : ifExpression? actionExpression EOF!
;
ifExpression
:'IF'! logicalConditionExpression
;
logicalConditionExpression
: booleanAndConditionExpression ( BigOR^ booleanAndConditionExpression)*
;
booleanAndConditionExpression
: logicalCondition ( BigAND^ logicalCondition )*
;
BigAND : 'and'|'AND';
logicalCondition
: booleanAndCondition ( OR^ booleanAndCondition )*
;
OR:'||';
booleanAndCondition
: evalCondition ( AND^ evalCondition)*
;
AND: '&&';
evalCondition
: FieldID OPERATOR^ (FieldID|STRING)
;
actionExpression
: 'THEN'! (actionMessage | fieldAction | stateAction )
;
actionMessage
: ('DISPLAY_WARNING' | 'DISPLAY_ERROR')^ STRING
;
fieldAction
: ('DISABLE' | 'REQUIRED')^ FieldID ( ','! FieldID )*
;
stateAction
: 'STATE_LICENSE'^ stateName+ //(','! stateName)*
;
FieldID
:'0'..'9'+;
/* item : FIELD
| CHAR CHAR
;
*/
//class csharpTestLexer extends Lexer;
stateName
: CHAR CHAR (','|EOF) ->^(STATE CHAR+)
;
CHAR: ('a'..'z'|'A'..'Z')
;
WS : (' '
| '\t'
| '\n'
| '\r')
{ $channel = HIDDEN; }
//{ $channel = Hidden; }
;
OPERATOR
: '=='
| '!='
| '<='
| '>='
| '<'
| '>'
| 'TD'
| 'FD'
| 'PD'
| 'TY'
| 'LY'
| 'TM'
| 'LM'
| '+(DELTA%)>'
| '-(DELTA%)>'
| '+(DELTA)>'
| '-(DELTA)>'
| 'LIKE'
;
STRING
: '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
fragment
OCTAL_ESC
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESC
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
//fragment
BigOR: 'or'|'OR';
答案 0 :(得分:4)
词法分析器独立于解析器创建令牌。因此,如果解析器在给定点“需要”两个CHAR
标记并不重要,如果词法分析器“看到”文本"OR"
,它将始终创建BigOR
标记。你无能为力。
在您的情况下,您只需让stateName
匹配两个CHAR
令牌或一个OR
令牌,就像这样:
stateName
: name (','|EOF) ->^(STATE name)
;
name
: CHAR CHAR
| BigOR
;
解析输入"THEN STATE_LICENSE AL,OR,PA"
将导致以下AST:
请注意,OR
是一个令牌,与其他令牌不同,其类型为CHAR
且其字符分开。如果您希望OR
节点的行为也是如此,请执行以下操作:
name
: CHAR CHAR
| BigOR -> CHAR[""+$BigOR.text.charAt(0)] CHAR[""+$BigOR.text.charAt(1)]
;
导致:
或者,如果您想要连接两个单独的字符,请执行:
name
: (CHAR CHAR | BigOR) -> CHAR[$text]
;
导致: