Error : '(' came as a complete surprise to me while looking for lexer rule element

Error : '(' came as a complete surprise to me while looking for lexer rule element

我尝试为以下作业匹配 STRING_LITERAL

细绳 字符串文字包含零个或多个由双精度包围的字符 引号 (”)。使用转义序列(下面列出)来表示特殊 字符串中的字符。请记住,引号不是 字符串。这是换行符或 EOF 字符的编译时错误 出现在开始 (”) 之后和结束匹配 (”) 之前。 所有支持的转义序列如下:

\b 退格
\f 换页
\r 回车 return
\n 换行
\t 水平制表符
\' 单引号
\ 反斜杠
字符串中的双引号(”),前面必须写一个单引号(’):’”双引号
例如:
”这是一个包含制表符 \t 的字符串”
”他问我:‘‘约翰在哪里?’””

一开始我的代码是这样的:

// Every char that isn't ESC_ILLEGAL or is ESC_SEQ 
STRING_LITERAL: '"' STR_CHAR* '"';

fragment STR_CHAR: ~ESC_ILLEGAL| ESC_SEQ;

fragment ESC_SEQ: ([\] [btnfr'\]) | [{'"}];

fragment ESC_ILLEGAL: (([\] ~[btnfr'\]) | ['] ~["]);

但由于 ANTLR 语法问题,我不得不内联 ESC_ILLEGAL,我的最终代码是这样的:

STRING_LITERAL: '"' STR_CHAR* '"';

fragment STR_CHAR: ~(([\] ~[btnfr'\]) | ['] ~["]) | ESC_SEQ;

fragment ESC_SEQ: ([\] [btnfr'\]) | [{'"}];

现在 ANTLR 抛出错误:'(' came as a complete surprise to me while looking for lexer rule element
我试图搜索此错误,甚至使用 De Morgan 更改我的 STR_CHAR 来取悦 ANTLR(但这不起作用,因为 AND 不受 ANTLR 支持)。顺便说一句,我不太确定我的 STRING_LITERAL 是否正确,如果你能为此提供一些建议,那就太好了。我是 ANTLR 的新手,所以也许我做的很多事情看起来都错了,但如果可以的话请帮助我。

提前致谢。

这个任务由两部分组成:

  • 收集组成字符串的所有部分。
  • 对其某些内容应用语义。

第一部分可以用这些简单的规则来完成:

String:
    DOUBLE_QUOTE InnerString* DOUBLE_QUOTE
;

fragment InnerString:
    SINGLE_QUOTE DOUBLE_QUOTE InnerString SINGLE_QUOTE DOUBLE_QUOTE
    | .
;

DOUBLE_QUOTE: '"';
SINGLE_QUOTE: '\'';

与您的解决方案相比,该解决方案似乎并未专门处理转义序列。这是因为如果您在语法中定义序列,那么处理错误(即错误的序列)会更加困难。处理转义序列意味着将含义(语义)应用于字符串的一部分。语义处理最好在解析 运行.

之后的单独步骤中完成

在语义步骤中,您将扫描标记文本以查找任何 \<letter> 序列并将它们转换为实际目标值。如果您遇到一个无效的序列,您可以打印一条很好的错误消息,如果允许的转义码出现在词法分析器语法中,这是不可能的。解析 运行 只会以“没有可行的 alt”之类的神秘消息停止。

仅当否定集中有单个字符时,才能在词法分析器中否定字符集。所以这是有效的:

FOO : ~(('a' | 'b') | 'c');

但这不是:

FOO : ~(('ab') | 'c'); // 'ab' cannot be negated

你的问题是这样的:

~(([\] ~[btnfr'\]) | ['] ~["])

你不能否定任何与 (([\] ~[btnfr'\]) | ['] ~["]) 匹配的东西。