微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Antlr4:如何避免过多的语义谓词?

如何解决Antlr4:如何避免过多的语义谓词?

这是我的词法分析器规则的开始:

F_TEXT_START
    : {! matchingFText}? 'f"' {matchingFText = true;}
    ;

F_TEXT_PH_ESCAPE
    : {matchingFText && ! matchingFTextPh}? '{=/'
    ;

F_TEXT_PH_START
    : {matchingFText && ! matchingFTextPh}? '{=' {matchingFTextPh = true;}
    ;

F_TEXT_PH_END
    : {matchingFText && matchingFTextPh}? '}' {matchingFTextPh = false;}
    ;

F_TEXT_CHAR
    : {matchingFText && ! matchingFTextPh}? (~('"' | '{')+ | '""' | '{' ~'=')
    ;

F_TEXT_END
    : {matchingFText && ! matchingFTextPh}? '"' {matchingFText = false;}
    ;


IF
    : {! matchingFText || matchingFTextPh}? 'if'
    ;

ELIF
    : {! matchingFText || matchingFTextPh}? 'elif'
    ;

// Lots of other keywords

fragment LETTER
    : ('A' .. 'Z' | 'a' .. 'z' | '_')
    ;
    
VARIABLE
    : {! matchingFText || matchingFTextPh}? LETTER (LETTER | DIGIT)*
    ;

我正在做的是将格式化后的文本不仅像普通文本标记一样放置,而且之前加上a,但我将其添加到解析树中,以便能够分辨解析时是否有错误(仅{{1 }}。因此,格式化的文本以parser.start()开头,以f"结尾,任何"必须替换为",并且可以包含以""开头并以结尾结尾的占位符与{=一起使用,但是如果您想实际编写},则必须将其替换为{=。 问题在于,在普通格式的文本内容(而不是占位符)中,词法分析器不仅开始处理{=/,而且还开始处理其他词法分析器规则,例如变量。我所做的工作似乎很愚蠢,我只是将语义谓词用于其他所有规则,以避免它们在格式化文本的内容中(但仍在占位符中)匹配。

没有更好的方法吗?

解决方法

为此,我将使用词汇模式。要使用词法模式,您必须定义单独的词法分析器和解析器语法。这是一个快速演示:

lexer grammar TestLexer;

F_TEXT_START
 : 'f"' -> pushMode(F_TEXT)
 ;

VARIABLE
 : LETTER (LETTER | DIGIT)*
 ;

F_TEXT_PH_ESCAPE
 : '{=/'
 ;

F_TEXT_PH_END
 : '}' -> popMode
 ;

SPACES
 : [ \t\r\n]+ -> skip
 ;

fragment LETTER
 : [a-zA-Z_]
 ;

fragment DIGIT
 : [0-9]
 ;

mode F_TEXT;

  F_TEXT_CHAR
   : ~["{]+ | '""' | '{' ~'='
   ;

  F_TEXT_PH_START
    : '{=' -> pushMode(DEFAULT_MODE)
    ;

  F_TEXT_END
   : '"' -> popMode
   ;

像这样在解析器中使用词法分析器:

parser grammar TestParser;

options {
  tokenVocab=TestLexer;
}

// ...

如果您现在对输入f"mu {=mu}" mu进行标记,则将获得以下标记:

F_TEXT_START              `f"`
F_TEXT_CHAR               `mu `
F_TEXT_PH_START           `{=`
VARIABLE                  `mu`
F_TEXT_PH_END             `}`
F_TEXT_END                `"`
VARIABLE                  `mu`

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。