我正在学习制作一个编译器,它有一些规则,比如单个字符串:
char ch[] ="abcd";
和多字符串:
printf("This is\
a multi\
string");
我写了正则表达式
STRING \"([^\"\n]|\\{NEWLINE})*\"
单行字符串工作正常,但它不适用于多行字符串,其中一行以'\'
字符结尾。
我应该改变什么?
答案 0 :(得分:0)
常见的字符串模式是
\"([^"\\\n]|\\(.|\n))*\"
这将匹配包含转义双引号(\"
)和反斜杠(\\
)的字符串。它使用\\(.|\n)
允许反斜杠后的任何字符。虽然一些反斜杠序列长于一个字符(\x40
),但它们都不包括第一个字符后的非字母数字。
您的输入可能包含Windows行结尾(CR-LF),在这种情况下,反斜杠不会直接跟在换行符后面;然后是回车。如果你想接受那个输入而不是抛出错误(这可能更合适),你需要明确地这样做:
\"([^"\\\n]|\\(.|\r?\n))*\"
但是识别字符串并理解字符串代表的是两个不同的东西。通常,编译器需要将字符串的表示形式转换为字节序列,例如,需要将\n
转换为字节10并完全删除反斜杠的换行符。
使用启动条件可以在(f)lex扫描仪中轻松完成该任务。 (或者,当然,您可以使用不同的词法扫描程序重新扫描字符串。)
此外,您需要考虑错误处理。一旦你用未转义的换行符禁止字符串(就像C那样),你就可以打开一个未终止字符串的可能性,在结束语句之前会遇到一个换行符。如果字符串未正确关闭,则文件末尾可能会发生同样的情况。
如果您有单字符后备规则,它将识别未终止字符串的开头引号。这是不可取的,因为它会将字符串的内容扫描为程序文本,从而导致一连串的错误。如果您没有尝试进行错误恢复,那么这并不重要,但如果您这样做,通常最好至少使用不同的模式识别未终止的字符串,直到换行符为止。