ANTLR4 使用 HIDDEN 通道会导致错误,而使用 skip 则不会
ANTLR4 using HIDDEN channel causes errors while using skip does not
在我的语法中我使用:
WS: [ \t\r\n]+ -> skip;
当我将其更改为使用隐藏频道时:
WS: [ \t\r\n]+ -> channel(HIDDEN);
我收到错误(无关输入“”...)我在使用 'skip' 时没有收到。
我认为,如果涉及传递给解析器的内容,则跳过和发送到频道没有区别。
您可以在下面找到执行解析器的代码摘录:
CharStream charStream = new ANTLRInputStream(formulaString);
FormulaLexer lexer = new FormulaLexer(charStream);
BufferedTokenStream tokens = new BufferedTokenStream(lexer);
FormulaParser parser = new FormulaParser(tokens);
ParseTree tree = parser.startRule();
StartRuleVisitor startRuleVisitor = new StartRuleVisitor();
startRuleVisitor.visit(tree);
VariableVisitor variableVisitor = new VariableVisitor(tokens);
variableVisitor.visit(tree);
还有语法本身:
grammar Formula;
startRule
: variable RELATION_OPERATOR integer
;
integer
: DIGIT+
;
identifier
: (LETTER | DIGIT) ( DIGIT | LETTER | '_' | '.')+
;
tableId
: 'T_' (identifier | WILDCARD)
;
rowId
: 'R_' (identifier | WILDCARD)
;
columnId
: 'C_' (identifier | WILDCARD)
;
sheetId
: 'S_' (identifier | WILDCARD)
;
variable
: L_CURLY_BRACKET cellIdComponent (COMMA cellIdComponent)+ R_CURLY_BRACKET
;
cellIdComponent
: tableId | rowId | columnId | sheetId
;
COMMA
: ','
;
RELATION_OPERATOR
: EQ
;
WILDCARD
: 'NNN'
;
L_CURLY_BRACKET
: '{'
;
R_CURLY_BRACKET
: '}'
;
LETTER
: ('a' .. 'z') | ('A' .. 'Z')
;
DIGIT
: ('0' .. '9')
;
EQ
: '='
| 'EQ' | 'eq'
;
WS
: [ \t\r\n]+ -> channel(HIDDEN)
;
我尝试解析的字符串:
{T_C 00.01, R_010, C_010} = 1
我使用通道(隐藏)获得的输出:
line 1:4 extraneous input ' ' expecting {'_', '.', LETTER, DIGIT}
line 1:11 extraneous input ' ' expecting {'T_', 'R_', 'C_', 'S_'}
line 1:18 extraneous input ' ' expecting {'T_', 'R_', 'C_', 'S_'}
line 1:27 extraneous input ' ' expecting RELATION_OPERATOR
line 1:29 extraneous input ' ' expecting DIGIT
但是如果我将频道(隐藏)更改为 'skip' 则没有错误。
此外,我观察到对于比这更复杂的语法,如果我使用 channel(HIDDEN) 我会得到 'no viable alternative at input...' 并且 'skip'.[=16 的错误再次消失=]
你知道可能是什么原因吗?
您应该使用 CommonTokenStream
而不是 BufferedTokenStream
。参见 BufferedTokenStream
description on github:
This token stream ignores the value of {@link Token#getChannel}. If your
parser requires the token stream filter tokens to only those on a particular
channel, such as {@link Token#DEFAULT_CHANNEL} or
{@link Token#HIDDEN_CHANNEL}, use a filtering token stream such a
{@link CommonTokenStream}.
在我的语法中我使用:
WS: [ \t\r\n]+ -> skip;
当我将其更改为使用隐藏频道时:
WS: [ \t\r\n]+ -> channel(HIDDEN);
我收到错误(无关输入“”...)我在使用 'skip' 时没有收到。 我认为,如果涉及传递给解析器的内容,则跳过和发送到频道没有区别。
您可以在下面找到执行解析器的代码摘录:
CharStream charStream = new ANTLRInputStream(formulaString);
FormulaLexer lexer = new FormulaLexer(charStream);
BufferedTokenStream tokens = new BufferedTokenStream(lexer);
FormulaParser parser = new FormulaParser(tokens);
ParseTree tree = parser.startRule();
StartRuleVisitor startRuleVisitor = new StartRuleVisitor();
startRuleVisitor.visit(tree);
VariableVisitor variableVisitor = new VariableVisitor(tokens);
variableVisitor.visit(tree);
还有语法本身:
grammar Formula;
startRule
: variable RELATION_OPERATOR integer
;
integer
: DIGIT+
;
identifier
: (LETTER | DIGIT) ( DIGIT | LETTER | '_' | '.')+
;
tableId
: 'T_' (identifier | WILDCARD)
;
rowId
: 'R_' (identifier | WILDCARD)
;
columnId
: 'C_' (identifier | WILDCARD)
;
sheetId
: 'S_' (identifier | WILDCARD)
;
variable
: L_CURLY_BRACKET cellIdComponent (COMMA cellIdComponent)+ R_CURLY_BRACKET
;
cellIdComponent
: tableId | rowId | columnId | sheetId
;
COMMA
: ','
;
RELATION_OPERATOR
: EQ
;
WILDCARD
: 'NNN'
;
L_CURLY_BRACKET
: '{'
;
R_CURLY_BRACKET
: '}'
;
LETTER
: ('a' .. 'z') | ('A' .. 'Z')
;
DIGIT
: ('0' .. '9')
;
EQ
: '='
| 'EQ' | 'eq'
;
WS
: [ \t\r\n]+ -> channel(HIDDEN)
;
我尝试解析的字符串:
{T_C 00.01, R_010, C_010} = 1
我使用通道(隐藏)获得的输出:
line 1:4 extraneous input ' ' expecting {'_', '.', LETTER, DIGIT}
line 1:11 extraneous input ' ' expecting {'T_', 'R_', 'C_', 'S_'}
line 1:18 extraneous input ' ' expecting {'T_', 'R_', 'C_', 'S_'}
line 1:27 extraneous input ' ' expecting RELATION_OPERATOR
line 1:29 extraneous input ' ' expecting DIGIT
但是如果我将频道(隐藏)更改为 'skip' 则没有错误。
此外,我观察到对于比这更复杂的语法,如果我使用 channel(HIDDEN) 我会得到 'no viable alternative at input...' 并且 'skip'.[=16 的错误再次消失=]
你知道可能是什么原因吗?
您应该使用 CommonTokenStream
而不是 BufferedTokenStream
。参见 BufferedTokenStream
description on github:
This token stream ignores the value of {@link Token#getChannel}. If your parser requires the token stream filter tokens to only those on a particular channel, such as {@link Token#DEFAULT_CHANNEL} or {@link Token#HIDDEN_CHANNEL}, use a filtering token stream such a {@link CommonTokenStream}.