在 ANTLR4 中括号周围至少有一个 Space
Atleast ONE Space around Parenthesis in ANTLR4
我想要 space 在 括号 周围 IF 条件 。至少需要一个 space。但是当我在语法中使用 Space 时它会抛出错误, 当我使用 Else 块时 。请帮助我,如何完成它,我看到了很多例子,但 none 与它有关。
我只需要在 If condition.
的 Parenthesis 周围 spaces
prog: stat_block EOF;
stat_block: OBRACE block CBRACE;
block: (stat (stat)*)?;
stat: expr ';'
| IF condition_block (ELSE stat_block)?
;
expr
: expr SPACE ('*' | '/') SPACE expr
| ID
| INT
| STRING
;
exprList: expr (',' expr)*;
condition_block: SPACE OPAR SPACE expr SPACE CPAR SPACE stat_block;
IF: 'IF';
ELSE: 'ELSE';
OPAR: '(';
CPAR: ')';
OBRACE: '{';
CBRACE: '}';
SPACE: SINGLE_SPACE+;
SINGLE_SPACE: ' ';
ID: [a-zA-Z]+;
INT: [0-9]+;
NEWLINE: '\r'? '\n' -> skip;
WS: [ \t]+ -> skip;
需要解析的输入
IF ( 3 ) { } ELSE { }
当前输入
At least one space is required.
那么你要么:
- 不能
-> skip
WS
规则,这将导致 所有 space 和选项卡成为标记并需要您的解析器处理它们正确(这可能会在您的解析器规则中变得一团糟!),或者
- 你让
WS -> skip
保持原样,但在你的 PAREN
规则中包含一个 space:OPAR : ' ( '; CPAR: ' ) ';
(如果可能的话,也可以使用制表符)
几乎所有语言都忽略空格是有原因的。如果您不忽略它,那么您必须处理它可能存在于令牌流中的任何地方,无论它是否存在于您的所有解析器规则中。
您可以尝试在 Lexer 规则中包含您想要用空格包裹的标记的空格,但仍然可能会发现意外。
建议:如果 -> skip;
用于您的 WS
规则,请使用 -> channel(HIDDEN);
这会将标记保留在标记流中,以便您可以在代码中查找它们,但“隐藏" 来自解析器规则的空白标记。这也允许 ANTLR 对您的输入进行正确的解释,并构建一个正确表示它的解析树。
如果您真的 想要坚持使用空格 before/after,您可以在监听器中编写代码,让 before/after 看起来是输入流中的标记查看您是否有空格,并生成您自己的错误(可以非常具体地说明您的要求)。
我想要 space 在 括号 周围 IF 条件 。至少需要一个 space。但是当我在语法中使用 Space 时它会抛出错误, 当我使用 Else 块时 。请帮助我,如何完成它,我看到了很多例子,但 none 与它有关。 我只需要在 If condition.
的 Parenthesis 周围 spacesprog: stat_block EOF;
stat_block: OBRACE block CBRACE;
block: (stat (stat)*)?;
stat: expr ';'
| IF condition_block (ELSE stat_block)?
;
expr
: expr SPACE ('*' | '/') SPACE expr
| ID
| INT
| STRING
;
exprList: expr (',' expr)*;
condition_block: SPACE OPAR SPACE expr SPACE CPAR SPACE stat_block;
IF: 'IF';
ELSE: 'ELSE';
OPAR: '(';
CPAR: ')';
OBRACE: '{';
CBRACE: '}';
SPACE: SINGLE_SPACE+;
SINGLE_SPACE: ' ';
ID: [a-zA-Z]+;
INT: [0-9]+;
NEWLINE: '\r'? '\n' -> skip;
WS: [ \t]+ -> skip;
需要解析的输入
IF ( 3 ) { } ELSE { }
当前输入
At least one space is required.
那么你要么:
- 不能
-> skip
WS
规则,这将导致 所有 space 和选项卡成为标记并需要您的解析器处理它们正确(这可能会在您的解析器规则中变得一团糟!),或者 - 你让
WS -> skip
保持原样,但在你的PAREN
规则中包含一个 space:OPAR : ' ( '; CPAR: ' ) ';
(如果可能的话,也可以使用制表符)
几乎所有语言都忽略空格是有原因的。如果您不忽略它,那么您必须处理它可能存在于令牌流中的任何地方,无论它是否存在于您的所有解析器规则中。
您可以尝试在 Lexer 规则中包含您想要用空格包裹的标记的空格,但仍然可能会发现意外。
建议:如果 -> skip;
用于您的 WS
规则,请使用 -> channel(HIDDEN);
这会将标记保留在标记流中,以便您可以在代码中查找它们,但“隐藏" 来自解析器规则的空白标记。这也允许 ANTLR 对您的输入进行正确的解释,并构建一个正确表示它的解析树。
如果您真的 想要坚持使用空格 before/after,您可以在监听器中编写代码,让 before/after 看起来是输入流中的标记查看您是否有空格,并生成您自己的错误(可以非常具体地说明您的要求)。