我学习做一个编译器,它有一个像一个字符串的一些规则:什么是多字符串的正则表达式?
char ch[] ="abcd";
和多串:
printf("This is\
a multi\
string");
我写的正则表达式
STRING \"([^\"\n]|\\{NEWLINE})*\"
它的工作原理单线字符串很好,但它不适用于多行字符串,其中一行以'\'
字符结尾。 我应该改变什么?
我学习做一个编译器,它有一个像一个字符串的一些规则:什么是多字符串的正则表达式?
char ch[] ="abcd";
和多串:
printf("This is\
a multi\
string");
我写的正则表达式
STRING \"([^\"\n]|\\{NEWLINE})*\"
它的工作原理单线字符串很好,但它不适用于多行字符串,其中一行以'\'
字符结尾。 我应该改变什么?
一个常见的字符串模式是
\"([^"\\\n]|\\(.|\n))*\"
这将匹配其中包括转义双引号(\"
)和反斜杠(\\
)字符串。它使用\\(.|\n)
来允许反斜杠后的任何字符。尽管一些反斜杠序列长于一个字符(\x40
),但它们都不包含第一个字符后面的非字母数字。
您的输入可能包含Windows行尾(CR-LF),在这种情况下,反斜杠不会紧跟换行符;它会跟着一个回车。如果你想接受输入,而不是抛出一个错误(这可能是更合适),你需要明确这样做:
\"([^"\\\n]|\\(.|\r?\n))*\"
但识别字符串,并了解该字符串代表是两回事。通常情况下,编译器需要将字符串的表示形式转换为字节序列,例如,需要将\n
转换为字节10并全部删除反斜杠的换行符。
使用启动条件,可以在(f)lex扫描仪中轻松完成该任务。 (或者,当然,您可以使用不同的词法扫描仪重新扫描字符串。)
此外,您需要考虑错误处理。一旦你禁止带有非转义换行符的字符串(就像C一样),你就可以打开一扇未结束字符串的大门,在结束引号之前遇到一个换行符。如果字符串未正确关闭,则文件末尾可能会发生同样的情况。
如果您有单字符回退规则,它将识别未终止字符串的开始引号。这是不可取的,因为它会将字符串的内容扫描为导致错误级联的程序文本。如果你没有尝试错误恢复,那并不重要,但是如果你是这样的话,通常最好至少用新模式识别未结束的字符串,直到换行符为止。
为什么使用定义'{NEWLINE}'(其值不显示)而不是更易读的'\ n'?它使你的代码难以阅读,而且你的问题很难回答,因为它很可能与不必要的定义中的错误有关。另外,你不需要在字符类('[[...]')内跳过引号。 – rici
此前,在我的代码中,我编写了NEWLINE \ n规则。所以,无论我需要什么\ n,我都写了NEWLINE,并且是的,我不需要在字符类中逃避引号。 – sphoenix
您如何编写代码当然是您的决定。但是如果你使用一个定义,那么你需要将它包含在你的问题中;否则我们怎么能知道真正的定义是什么?问题代码应该是独立的。如果定义是正确的,那么正则表达式也是如此,并且问题可能与输入中的尾随空格有关。或者你的规则中的其他地方,尽管这会有点奇怪。提供[mcve]总是更好。 – rici