忽略 Antlr4 中的空格(在某些部分)
Ignoring whitespace (in certain parts) in Antlr4
我对antlr不是很熟悉。我使用的是第 4 版,我有一个语法,其中空格在某些部分并不重要(但在其他部分可能很重要,或者更确切地说是运气)。
假设我们有以下语法
grammar Foo;
program : A* ;
A : ID '@' ID '(' IDList ')' ';' ;
ID : [a-zA-Z]+ ;
IDList : ID (',' IDList)* ;
WS : [ \t\r\n]+ -> skip ;
和一个测试输入
foo@bar(X,Y);
foo@baz ( z,Z) ;
第一行解析正确,第二行解析错误。
我不想用空格不相关的地方污染我的规则,因为我的实际语法比玩具示例更复杂。如果不清楚,部件 ID'@'ID 不应有空格。任何其他位置的空格根本不重要。
将 ID '@' ID
定义为词法分析器标记而不是解析器标记。
A : AID '(' IDList ')' ';' ;
AID : [a-zA-Z]+ '@' [a-zA-Z]+;
其他选项
- enable/disable 令牌流中的空格,例如
- enable/disable 带有词法分析器模式的空格(可能是一个问题,因为词法分析器模式是在上下文中触发的,这在您的情况下不容易确定)
即使您跳过了 WS,词法分析器规则仍然对空白字符的存在很敏感。跳过只是意味着没有生成令牌供解析器使用。因此,词法分析器 Addr
规则明确不允许任何内部空白字符。
相反,a
和 idList
解析器规则永远不会看到内部空白标记,因此这些规则对生成的标记之间出现的空白字符不敏感。
grammar Foo;
program : a* EOF ; // EOF will require parsing the entire input
a : Addr LParen IDList RParen Semi ;
idList : ID (Comma ID)* ; // simpler equivalent construct
Addr : ID '@' ID ;
ID : [a-zA-Z]+ ;
WS : [ \t\r\n]+ -> skip ;
我对antlr不是很熟悉。我使用的是第 4 版,我有一个语法,其中空格在某些部分并不重要(但在其他部分可能很重要,或者更确切地说是运气)。
假设我们有以下语法
grammar Foo;
program : A* ;
A : ID '@' ID '(' IDList ')' ';' ;
ID : [a-zA-Z]+ ;
IDList : ID (',' IDList)* ;
WS : [ \t\r\n]+ -> skip ;
和一个测试输入
foo@bar(X,Y);
foo@baz ( z,Z) ;
第一行解析正确,第二行解析错误。 我不想用空格不相关的地方污染我的规则,因为我的实际语法比玩具示例更复杂。如果不清楚,部件 ID'@'ID 不应有空格。任何其他位置的空格根本不重要。
将 ID '@' ID
定义为词法分析器标记而不是解析器标记。
A : AID '(' IDList ')' ';' ;
AID : [a-zA-Z]+ '@' [a-zA-Z]+;
其他选项
- enable/disable 令牌流中的空格,例如
- enable/disable 带有词法分析器模式的空格(可能是一个问题,因为词法分析器模式是在上下文中触发的,这在您的情况下不容易确定)
即使您跳过了 WS,词法分析器规则仍然对空白字符的存在很敏感。跳过只是意味着没有生成令牌供解析器使用。因此,词法分析器 Addr
规则明确不允许任何内部空白字符。
相反,a
和 idList
解析器规则永远不会看到内部空白标记,因此这些规则对生成的标记之间出现的空白字符不敏感。
grammar Foo;
program : a* EOF ; // EOF will require parsing the entire input
a : Addr LParen IDList RParen Semi ;
idList : ID (Comma ID)* ; // simpler equivalent construct
Addr : ID '@' ID ;
ID : [a-zA-Z]+ ;
WS : [ \t\r\n]+ -> skip ;