繁体   English   中英

Antlr4/Java:如何根据调用它的解析器规则制作一个跳过标记(词法分析器)的语义谓词

[英]Antlr4/Java : how to make a semantic predicate that skips a token (lexer) according to the parser rule that calls it

我想使用我的词法分析器规则

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
    ;

并制作一个语义谓词,例如“如果调用解析器规则不是line ,则skip(); it”。 现在我只需要帮助来做到这一点。

我希望我很清楚!

PS:如果不清楚,我正在使用 Java 作为主要语言

您可以跟踪您遇到的(并减少此数字,如果您遇到 a ) )。 然后,如果此数字等于 0,则仅创建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被跳过,而)后面的则没有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM