我正在上一门课,学习常规语法。我需要制作一个常规语法来识别 C++ 或 Java 程序中的注释。注释以 /* 开头,以 */ 结尾,中间的任何内容都可以忽略。我不考虑嵌套评论的情况。我可以在开头、结尾和中间有任意数量的 * 字符。我不确定如何处理中间的笔划。到目前为止我所做的如下我不确定我的想法是否正确。谢谢。
S => /A
A=> *B
B=> *B
B=> digitB
B=> letterB
B=> symbolB
B=> *C
C=> /D
D=> end
答案 0 :(得分:1)
您的描述不正确:
<块引用>注释以 /* 开头,以 */ 结尾,中间的任何内容都可以忽略。
应该是:
<块引用>注释以 /* 开始,以 */ 结束,中间除了 */ 之外的任何内容。
所以——正如你所说的——星号可以出现在评论中,并且可以多次出现。
这意味着扫描和测试单个字符不足以判断您是否仍在评论正文中,因为星号很可能是评论的内部字符或终止符的一部分。 >
例如在/****/
A=> *B
,B=> *B
,B=> *B
或 B=> *C
匹配,除非您选择B=> *C
然后测试并失败C=> /D
,否则您将不知道哪个是正确的。如果失败,您需要回溯并假设它是 B=> *B
。
但是,如果您将 B=> *B
作为第一个猜测,您可以接受 */ 序列作为评论的内容而不是评论的终止符。
我想您需要区分与评论内容相对应的两种状态:一种跟在星号后面,一种跟在其他任何东西后面。
让 B 表示一般评论内容,Q 表示星号后的内容。然后:
S=> / A
A=> * B
B=> [anything-except-asterisk] B
B=> * Q
Q=> [anything-except-slash] B
B=> * C
C=> / D
D=> end
可能会,我想。
当然,B=> * Q
和 B=> * C
之间仍然存在歧义,但是根据这个定义,每个选择都会被下一个输入字符确认或丢弃。
至少你知道你不会误解 */ 对,并让它作为评论的内容。