【发布时间】:2015-11-18 08:17:07
【问题描述】:
所以我们知道
// 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
我听说他们不递归的原因是因为他们会slow down the compiler,我想这是有道理的。但是现在当我用更高级的语言(比如 Python)解析 c++ 代码时,我可以简单地使用正则表达式
"\/[\/]+((?![\n])[\s\S])*\r*\n"
匹配// single line comments,并使用
"\/\*((?!\*\/)[\s\S])*\*\/"
匹配/* multiline comments */,然后遍历所有单行 cmets,删除它们,然后遍历所有多行 cmets 并删除它们。或相反亦然。但这就是我卡住的地方。似乎只做其中一个是不够的,因为:
// /*
An error is thrown because the /* is ignored
*/
/*
This doesn't affect things because of mysterious reasons
// */
和
/*
This throws an error because the second * / is unmatched
// */ */
这种行为的原因是什么?它也是编译器解析事物方式的产物吗?明确地说,我不想改变 c++ 的行为,我只想知道第二组示例的行为背后的原因。
编辑:
所以是的,更明确地说,我的问题是为什么以下三种(看似合理的)解释这种行为的方式不起作用:
不管是 /* 还是 * /,只要忽略 // 之后的所有字符,即使您在多行注释中。
允许 / * 或 */ 后跟 // 仍然有效。
以上两者。
我理解为什么不允许嵌套 cmets,因为它们需要堆栈和任意大量的内存。但这三种情况不会。
再次编辑:
如果有人感兴趣,这里是下面的代码,按照此处讨论的正确注释规则,在 python 中提取 c/c++ 文件的 cmets:
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")
【问题讨论】:
-
您说过“它不会那么慢”,但没有说明为什么应该更改语言以允许嵌套 cmets。如果你能提供一个,我可以告诉你为什么它不如让事情保持原样重要。
-
好的,我同意,但这不是重点。
-
好吧,现在我很困惑。您是在问为什么我们在 C++ 中没有嵌套的 cmets,或者如果我们没有,如何解析 C++? (这比我们这样做更容易...)
-
@DanielleEnsign
//不能注释掉*/,因为//被/*注释掉了。 -
#if 0/#endif会很好地嵌套。
标签: c++ regex compiler-construction comments