什么是多字符串的正则表达式?

时间:2017-03-27 14:04:11

标签: lex

我正在学习制作一个编译器,它有一些规则,比如单个字符串:

char ch[] ="abcd";

和多字符串:

printf("This is\
a multi\
string");

我写了正则表达式

STRING \"([^\"\n]|\\{NEWLINE})*\"

单行字符串工作正常,但它不适用于多行字符串,其中一行以'\'字符结尾。 我应该改变什么?

1 个答案:

答案 0 :(得分:0)

常见的字符串模式是

\"([^"\\\n]|\\(.|\n))*\"

这将匹配包含转义双引号(\")和反斜杠(\\)的字符串。它使用\\(.|\n)允许反斜杠后的任何字符。虽然一些反斜杠序列长于一个字符(\x40),但它们都不包括第一个字符后的非字母数字。

您的输入可能包含Windows行结尾(CR-LF),在这种情况下,反斜杠不会直接跟在换行符后面;然后是回车。如果你想接受那个输入而不是抛出错误(这可能更合适),你需要明确地这样做:

\"([^"\\\n]|\\(.|\r?\n))*\"

但是识别字符串并理解字符串代表的是两个不同的东西。通常,编译器需要将字符串的表示形式转换为字节序列,例如,需要将\n转换为字节10并完全删除反斜杠的换行符。

使用启动条件可以在(f)lex扫描仪中轻松完成该任务。 (或者,当然,您可以使用不同的词法扫描程序重新扫描字符串。)

此外,您需要考虑错误处理。一旦你用未转义的换行符禁止字符串(就像C那样),你就可以打开一个未终止字符串的可能性,在结束语句之前会遇到一个换行符。如果字符串未正确关闭,则文件末尾可能会发生同样的情况。

如果您有单字符后备规则,它将识别未终止字符串的开头引号。这是不可取的,因为它会将字符串的内容扫描为程序文本,从而导致一连串的错误。如果您没有尝试进行错误恢复,那么这并不重要,但如果您这样做,通常最好至少使用不同的模式识别未终止的字符串,直到换行符为止。