我正在尝试在 ANTLR4 中实现表达式/公式语言,但在处理空格时遇到问题。在大多数情况下,我不关心空格,所以我有“标准”词法分析器规则将它发送到 HIDDEN 通道,即
// Whitespace
WS
: ( ' ' | '\t' |'\r' | '\n' ) -> channel(HIDDEN)
;
Run Code Online (Sandbox Code Playgroud)
但是,我有一个运算符,它之前或之后都不允许出现空格,而且我不知道如何在不更改 WS 词法分析器规则的情况下处理这种情况,以将空格保留在默认通道中,并且WS?在我的所有其他内容中都有明确的术语解析器规则(有很多)。
作为简化示例,我为虚构的谓词语言创建了以下语法:
grammar Logik;
/*
* Parser Rules
*/
ruleExpression
: orExpression
;
orExpression
: andExpression ( 'OR' andExpression)*
;
andExpression
: primaryExpression ( 'AND' primaryExpression)*
;
primaryExpression
: variableExpression
| '(' ruleExpression ')'
;
variableExpression
: IDENTIFIER ( '.' IDENTIFIER )*
;
/*
* Lexer Rules
*/
IDENTIFIER
: LETTER LETTERORDIGIT*
;
fragment LETTER …Run Code Online (Sandbox Code Playgroud) 当我调用令牌的文本属性时,我想保留空格,有什么办法吗?情况如下:我们有以下代码
IF L > 40 THEN;
ELSE
IF A = 20 THEN
PUT "HELLO";
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想将其转换为:
if (!(L>40){
if (A=20)
put "hello";
}
Run Code Online (Sandbox Code Playgroud)
Antlr中的规则是:
stmt_if_block: IF expr
THEN x=stmt
(ELSE y=stmt)?
{
if ($x.text.equalsIgnoreCase(";"))
{
WriteLn("if(!(" + $expr.text +")){");
WriteLn($stmt.text);
Writeln("}");
}
}
Run Code Online (Sandbox Code Playgroud)
但结果如下:
if(!(L>40))
{
ifA=20put"hello";
}
Run Code Online (Sandbox Code Playgroud)
原因是$stmt移除了空白区域.我想知道是否还有保留这些空白区域非常
感谢你
更新:如果我添加
SPACE: [ ] -> channel(HIDDEN);
Run Code Online (Sandbox Code Playgroud)
空间将被保留,结果如下所示,令牌之间有许多空格:
IF SUBSTR(WNAME3,M-1,1) = ')' THEN M = L; ELSE M = L - 1;
Run Code Online (Sandbox Code Playgroud) 我对 antlr 不太熟悉。我正在使用第 4 版,并且我有一个语法,其中空格在某些部分并不重要(但在其他部分可能很重要,或者更确切地说是它的运气)。
所以说我们有以下语法
grammar Foo;
program : A* ;
A : ID '@' ID '(' IDList ')' ';' ;
ID : [a-zA-Z]+ ;
IDList : ID (',' IDList)* ;
WS : [ \t\r\n]+ -> skip ;
Run Code Online (Sandbox Code Playgroud)
和一个测试输入
foo@bar(X,Y);
foo@baz ( z,Z) ;
Run Code Online (Sandbox Code Playgroud)
第一行被正确解析而第二行没有。我不想用空格不相关的地方来玷污我的规则,因为我的实际语法比玩具示例更复杂。如果不清楚部分 ID'@'ID 不应有空格。任何其他位置的空白都无关紧要。