goyacc动作中字符串字面量处理疑问:为何允许\ 却禁止 ?
解析goyacc中cpyact函数处理
\+换行序列的原因 这段代码的逻辑完全是为了支持C风格的字符串续行语法,和你猜测的一样,这确实和C字符串规则直接相关,而goyacc继承自Inferno的iyacc,后者本身就是类C工具链的一部分,所以保留了这个特性。
代码逻辑拆解
对应你标注的疑问逐一解释:
为什么专门处理
\+换行?
当代码遇到反斜杠\后,若下一个字符是换行符\n,只会增加行号lineno,不会将这个换行符写入输出。这对应C语言中允许用\紧跟换行来拆分长字符串的语法——编译器会忽略这个\和换行,把前后内容拼接成一个完整字符串。比如在C里:char s[] = "hello\ world";实际等价于
"helloworld",goyacc里的这段逻辑就是实现同样的效果,方便用户在yacc语法文件中把长字符串拆成多行书写,避免一行过长。为什么直接的换行(无前置
\)会报错?
代码里如果直接遇到换行符\n(没有被\转义),就触发errorf("newline in string"),这也完全符合C字符串的规则:未转义的换行是非法的,字符串必须用"/'闭合在同一行,或者用\续行拆分。
对应你的注释疑问
- 对于输入
"ab\\\ncd"(实际是ab+\+换行+cd),这段代码会处理为:写入\后,遇到换行只加行号,不写入换行,接着写入后续的cd,最终输出的字符串等价于"abcd",符合续行的预期。 - 而输入
"ab\ncd"(字符串内直接包含换行)会触发报错,因为没有前置\,违反了类C字符串的语法规则。
根源:继承自类C工具链的设计
goyacc衍生自Inferno的utils/iyacc/yacc.c,而iyacc是为类C环境打造的yacc实现,自然会沿用C语言的字符串语法规则,包括续行符的支持。这也是这段代码逻辑的由来。
内容的提问来源于stack exchange,提问作者Phi Quang Phuoc
相关产品推荐
相关产品推荐

