【发布时间】:2012-12-20 09:59:15
【问题描述】:
我知道如何使用 SKIP 声明跳过这些 cmets,但我需要做的就是获取一个 C 源代码并在没有 cmets 的情况下输出相同的源代码。
所以我声明了一个标记
有人可以帮帮我吗?
谢谢
【问题讨论】:
标签: java parsing comments parser-generator javacc
我知道如何使用 SKIP 声明跳过这些 cmets,但我需要做的就是获取一个 C 源代码并在没有 cmets 的情况下输出相同的源代码。
所以我声明了一个标记
有人可以帮帮我吗?
谢谢
【问题讨论】:
标签: java parsing comments parser-generator javacc
不要使用(~[])+:它会吞噬您的所有输入。这可能就是您没有看到令牌被跳过的原因。
在您的默认词法分析器模式下,当您遇到"/*"(多行注释的开头)时更改为不同的状态。在这个不同的统计数据中,要么匹配"*/"(并切换回默认的词法分析器状态),要么匹配任何字符~[](不是(~[])+!)。
快速演示:
PARSER_BEGIN(CommentStripParser)
public class CommentStripParser {
public static void main(String[] args) throws Exception {
java.io.FileInputStream file = new java.io.FileInputStream(new java.io.File(args[0]));
CommentStripParser parser = new CommentStripParser(file);
parser.parse();
}
}
PARSER_END(CommentStripParser)
TOKEN :
{
< OTHER : ~[] >
}
SKIP :
{
< "//" (~["\r", "\n"])* >
| < "/*" > : ML_COMMENT_STATE
}
<ML_COMMENT_STATE> SKIP :
{
< "*/" > : DEFAULT
| < ~[] >
}
void parse() :
{
Token t;
}
{
( t=<OTHER> {System.out.print(t.image);} )* <EOF>
}
给定测试文件:
/*
* comments
*/
class Test {
// more comments
int foo() {
return 42;
}
}
像这样运行演示(假设您有文件 CommentStripParser.jj、Test.java 和 JAR javacc.jar同一目录):
java -cp javacc.jar javacc CommentStripParser.jj 爪哇-cp。 *.java 爪哇-cp。 CommentStripParser Test.java
以下内容将打印到您的控制台:
class Test {
int foo() {
return 42;
}
}
(不再有 cmets)
请注意,您仍然需要考虑可能如下所示的字符串文字:
"the following: /*, is not the start of a comment"
和字符文字:
'"' // not the start of a string literal!
【讨论】:
OTHER-token 旁边为 STRING 和 CHAR 创建标记(不要忘记引号可以在字符串和字符文字中转义!):)