3

我正在尝试更新遵循以下规范的 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 语法)

我在 ANTRL 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 中使用 '\"""' 转义三引号字符串?

4

1 回答 1

0

您的一些 parer 规则实际上应该是词法分析器规则。并且SourceCharacter应该是一个fragment.

此外,EscapedTripleQuote* | SourceCharacter*您可能想要( EscapedTripleQuote | SourceCharacter )*. 第一个匹配aaa...or 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];
于 2017-09-10T11:27:47.830 回答