ANTLR语法:三引号字符串

4

我正在尝试更新一个遵循以下规范的ANTLR语法:

https://github.com/facebook/graphql/pull/327/files

从逻辑上讲,它被定义为:

StringValue ::
   - `"` StringCharacter* `"`
   - `"""` MultiLineStringCharacter* `"""`

StringCharacter ::
  - SourceCharacter but not `"` or \ or LineTerminator
  - \u EscapedUnicode
  - \ EscapedCharacter

MultiLineStringCharacter ::
  - SourceCharacter but not `"""` or `\"""`
  - `\"""`

请注意,上述内容是逻辑语句而不是ANTLR语法。

我在ANTLR 4中尝试了以下内容,但它无法识别三引号字符串中超过1个字符的内容。

string : triplequotedstring | StringValue ;

triplequotedstring: '"""' triplequotedstringpart?  '"""';

triplequotedstringpart : EscapedTripleQuote* | SourceCharacter*;

EscapedTripleQuote : '\\"""';

SourceCharacter :[\u0009\u000A\u000D\u0020-\uFFFF];

StringValue: '"' (~(["\\\n\r\u2028\u2029])|EscapedChar)* '"';

通过这些规则,它能够识别 '"""a"""',但当我添加更多字符时就会失败

例如:'"""abc"""' 无法解析,ANTLR 的 IntelliJ 插件也会提示

line 1:14 extraneous input 'abc' expecting {'"""', '\\"""', SourceCharacter}

我该如何在ANTLR中使用三重引号字符串并使用'\"""'转义符号?
1个回答

1

你的一些语法规则应该是词法规则。而SourceCharacter可能应该是一个fragment

此外,你可能想要使用( EscapedTripleQuote | SourceCharacter )*代替EscapedTripleQuote* | SourceCharacter*。前者匹配aaa...bbb...,而你可能想匹配aababbba...

尝试使用类似这样的代码:

string
 : Triplequotedstring 
 | StringValue 
 ;

Triplequotedstring
 : '"""' TriplequotedstringPart*? '"""'
 ;

StringValue
 : '"' ( ~["\\\n\r\u2028\u2029] | EscapedChar )* '"'
 ;

// Fragments never become a token of their own: they are only used inside other lexer rules
fragment TriplequotedstringPart : EscapedTripleQuote | SourceCharacter;
fragment EscapedTripleQuote : '\\"""';
fragment SourceCharacter :[\u0009\u000A\u000D\u0020-\uFFFF];

谢谢。我直接使用了上面的代码,看起来它让IDEA ANTLR插件很满意,所以我会在代码中试一下,看看效果如何。 - Brad Baker
哦,我说得有点早了——它太贪心了,所以像这样的输入:{ field(triple : """"triplestring""", triple2 : """another string""" ) }被合并为一个长三元字符串。 - Brad Baker
需要在片段上使用非贪婪的?指示符。 - Brad Baker
三重引号字符串部分:(转义的三引号|源字符)+?; - Brad Baker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接