String ANTLR:如何编写规则,在编写字符串时强制使用行连续字符?

String ANTLR:如何编写规则,在编写字符串时强制使用行连续字符?,string,antlr4,String,Antlr4,我想写一个规则来解析双引号内的字符串。当在多行上拆分字符串时,我想允许任何字符,唯一的条件是必须有一个行连续字符\ 例如: variable = "first line \n second line \ still second line \n \ third line" 如果在找到换行符之前找不到换行符,我希望解析器进行barf 我目前的规则是: STRING : '"' (ESC|.)*? '"'; fragment ESC : '\\'

我想写一个规则来解析双引号内的字符串。当在多行上拆分字符串时,我想允许任何字符,唯一的条件是必须有一个行连续字符\

例如:

variable = "first line \n second line \
            still second line \n \
            third line"
如果在找到换行符之前找不到换行符,我希望解析器进行barf

我目前的规则是:

STRING  : '"' (ESC|.)*? '"';
fragment ESC : '\\' [btnr"\\] ;
所以我允许字符串包含任何字符,包括一堆转义序列。但我并没有强制要求行继续字符\是拆分文本的必要条件

如何使语法强制执行该规则?

解决方案 解释 片段
ESCAPE
将匹配转义字符(特别是反斜杠和作为延续符号的新行字符)

令牌
STRING
将在双引号内匹配:

  • 转义字符(片段
    转义
  • 除新行和双引号外的所有内容
解决方案 解释 片段
ESCAPE
将匹配转义字符(特别是反斜杠和作为延续符号的新行字符)

令牌
STRING
将在双引号内匹配:

  • 转义字符(片段
    转义
  • 除新行和双引号外的所有内容

尽管已经有了一个公认的答案,但还是让我把我的答案写进去吧。我强烈建议不要在lexer规则中处理这种类型的错误。原因是您无法向用户提供正确的错误消息。首先,在ANTLR4中,lexer错误通常不会单独报告,它们显示为后续解析器错误。其次,产生的错误(可能类似于:“没有可行的alt at\n”)几乎是有用的


更好的解决方案是接受这两种变体(带换行符的换行符或不带转义符的换行符),然后进行语义检查。然后你就知道到底是什么错了,用户能说出你真正期望的是什么。

即使已经有了一个公认的答案,让我把我的答案放进去。我强烈建议不要在lexer规则中处理这种类型的错误。原因是您无法向用户提供正确的错误消息。首先,在ANTLR4中,lexer错误通常不会单独报告,它们显示为后续解析器错误。其次,产生的错误(可能类似于:“没有可行的alt at\n”)几乎是有用的


更好的解决方案是接受这两种变体(带换行符的换行符或不带转义符的换行符),然后进行语义检查。这样,您就可以准确地知道问题所在,用户也可以说出您真正的期望。

感谢您的详细回复!但问题是,我确实希望用户能够在字符串中写入“\r\n,\”。由于字符串包含在双引号中,如果用户希望将双引号嵌入到字符串中,则需要对其进行转义。如引号中的“第一行\n第二行”\“我的意思是,用户可以在字符串中嵌入反斜杠,后跟r、n或”。但是,在程序中定义字符串时,如果没有连续字符,他就不能按Enter键。如何区分用户编写的反斜杠+n和在编辑器中按Enter键时添加到字符串中的反斜杠(实际上在Windows上,\r\n已添加)再次感谢!)我试过了。似乎正确使用了\r和\n,并且当行继续符后面没有“Enter”时,我看到了错误。但是\“不起作用。例如:
“这是一个很长的描述\如果拆分中缺少行继续符,则会产生错误\但是\n\r\”应该可以\”“
Ok我对解决方案进行了最后一次更新。现在怎么样?:)现在可以了,因为行连续字符后面不需要跟新行。因此,该字符串要么匹配后跟任何内容的反斜杠,要么匹配任何不带反斜杠的字符\n或“我肯定能接受它。非常感谢:)感谢您的详细响应!但问题是我确实希望用户能够在字符串中写入\r\n、\”。由于字符串包含在双引号中,因此如果用户希望将双引号嵌入字符串,则需要对其进行转义。就像“第一行\n第二行\”中的引号\“我的意思是,用户可以嵌入反斜杠,后跟r、n或“在绳子上。但是,在程序中定义字符串时,如果没有连续字符,他就不能按Enter键。如何区分用户编写的反斜杠+n和在编辑器中按Enter键时添加到字符串中的反斜杠(实际上在Windows上,\r\n已添加)再次感谢!)我试过了。似乎正确使用了\r和\n,并且当行继续符后面没有“Enter”时,我看到了错误。但是\“不起作用。例如:
“这是一个很长的描述\如果拆分中缺少行继续符,则会产生错误\但是\n\r\”应该可以\”“
Ok我对解决方案进行了最后一次更新。现在怎么样?:)现在可以了,因为行连续字符后面不需要跟新行。因此,该字符串要么匹配后跟任何内容的反斜杠,要么匹配任何不匹配的字符\n或“我完全可以接受。非常感谢:)这就是我最初实现它的方式。我的字符串将完全匹配双引号内的任何内容。但当我开始强制执行限制时,我意识到手动检查这些限制的语义,而不是将规则嵌入语法中,对我来说会更加混乱。至于lexer错误,我最近了解到我可以重写ErrorListener和ErrorStrategy python类,并按照我想要的方式调整错误处理。因此,我将对此进行调查。谢谢你的洞察力!这就是我最初实现它的方式。我的字符串将完全匹配双引号内的任何内容。但当我开始发狂的时候
fragment ESCAPE
    : '\\' .
    ;
STRING
    : '"' (ESCAPE | ~[\n"])* '"'
    ;