问题描述
我想使用我的词法分析器规则
NEW_LINE : '\n' -> skip;
像正常规则一样。以此理解:我想忽略新行,除非它们是强制性的,以创建类似Python的语法。例如,在这里,新行将被忽略:
cook("banana","potatoe)
但是不能跳过新语句的新行,就像这样:
cook("banana","potatoe") vara = 12.4
,cook()
和分配之间必须有新的一行。这就是为什么我有时不得不跳过新行,但仍然将它们强制放在其他地方的原因。
这就是为什么我有了这个主意:
start
: line*
;
line
: line_expression (NEW_LINE | EOF)
;
line_expression
: expression
| assignment
;
expression
: Decimal
| Integer
| Text
| Boolean
;
并创建一个语义谓词,例如“如果调用解析器规则不是行,则skip();
。”
现在我只需要帮助即可。
我希望我很清楚!
PS:如果不清楚,我正在使用Java作为主要语言
解决方法
您可以跟踪遇到的(
的数目(如果遇到)
,请减少该数目)。然后,如果该数字等于零,则仅创建NL
个令牌。
这是一个快速演示:
grammar T;
@lexer::members {
int parensLevel = 0;
}
parse
: .*? EOF
;
OPAR : '(' {parensLevel++;};
CPAR : ')' {parensLevel--;};
NUMBER : [0-9]+ ( '.' [0-9]+)?;
STRING : '"' ~'"'* '"';
ASSIGN : '=';
COMMA : ',';
ID : [a-zA-Z]+;
SPACES : [ \t]+ -> skip;
NL : {parensLevel == 0}? [\r\n]+;
NL_SKIP : [\r\n]+ -> skip;
如果您向词法分析器提供以下输入:
cook("banana","potatoe")
varA = 12.4
将创建以下令牌:
ID `cook`
'(' `(`
STRING `"banana"`
',' `,`
STRING `"potatoe"`
')' `)`
NL `\n`
ID `varA`
'=' `=`
NUMBER `12.4`
如您所见,括号中的NL
被跳过,而)
之后的未被跳过。