Phy*_*ida 0 c++ regex compiler-construction comments
所以我们知道
// This doesn't affect anything
/*
This doesn't affect anything either
*/
/*
/* /* /*
This doesn't affect anything
*/
This does because comments aren't recursive
/* /*
This doesn't affect anything
*/ */
This throws an error because the second * / is unmatched since comments aren't recursive
Run Code Online (Sandbox Code Playgroud)
我听说它们不递归的原因是因为它们会减慢编译器的速度,我想这是有道理的。然而现在,当我用更高级的语言(比如 Python)解析 C++ 代码时,我可以简单地使用正则表达式
"\/[\/]+((?![\n])[\s\S])*\r*\n"
Run Code Online (Sandbox Code Playgroud)
匹配// single line comments并使用
"\/\*((?!\*\/)[\s\S])*\*\/"
Run Code Online (Sandbox Code Playgroud)
匹配/* multiline comments */,然后循环遍历所有单行注释,将其删除,然后循环遍历所有多行注释并将其删除。或相反亦然。但这就是我被困住的地方。似乎只做其中之一还不够,因为:
// /*
An error is thrown because the /* is ignored
*/
/*
This doesn't affect things because of mysterious reasons
// */
Run Code Online (Sandbox Code Playgroud)
和
/*
This throws an error because the second * / is unmatched
// */ */
Run Code Online (Sandbox Code Playgroud)
这种行为的原因是什么?它也是编译器解析事物的方式的产物吗?需要明确的是,我不想改变 C++ 的行为,我只想知道第二组示例的行为背后的原因。
编辑:
所以,是的,更明确地说,我的问题是为什么以下三种(看似合理的)解释这种行为的方法不起作用:
只需忽略 // 之后的行上的所有字符,无论它们是 /* 还是 * /,即使您位于多行注释中。
允许 / * 或 */ 后跟 // 仍然有效。
以上两者皆有。
我理解为什么不允许嵌套注释,因为它们需要堆栈和任意大量的内存。但这三种情况则不会。
再次编辑:
如果有人感兴趣,这里有以下代码,用于按照此处讨论的正确注释规则提取 python 中 ac/c++ 文件的注释:
import re
commentScanner = re.Scanner([
(r"\/[\/]+((?![\n])[\s\S])*\r*(\n{1})?", lambda scanner, token: ("//", token)),
(r"\/\*((?!\*\/)[\s\S])*\*\/", lambda scanner, token: ("/* ... */", token)),
(r"[\s\S]", lambda scanner, token: None)
])
commentScanner.scan("fds a45fsa//kjl fds4325lkjfa/*jfds/\nk\lj\/*4532jlfds5342a l/*a/*b/*c\n//fdsafa\n\r\n/*jfd//a*/fd// fs54fdsa3\r\r//\r/*\r\n2a\n\n\nois")
Run Code Online (Sandbox Code Playgroud)
这并不矛盾。现有行为既易于指定又易于实现,并且您的编译器正在正确实现它。请参阅标准中的 [lex.comment]。
\n\n\n\n\n字符
\n/*开始注释,以字符 结束*/。这些注释不嵌套。这些字符//开始注释,并以下一个换行符结束。如果此类注释中存在换页符或垂直制表符,则其与结束注释的换行符之间只能出现空格字符;无需诊断。[ 注意:注释字符\n//、/*、 和在注释*/中没有特殊含义//,并且像其他字符一样被处理。\n 同样,注释字符//和在注释/*中没有特殊含义/*。\xe2\x80\x94尾注]
正如您所看到的,//可用于注释掉/*和*/。只是注释不能嵌套,所以如果//已经在 a 内/*,那么//根本没有效果。