[英]“simple” parser for c++
我有一个项目(SCC),有点像C ++的REPL。 在灌木丛提示下我可以做
scc '2+2'
或更复杂一点:
scc 'double x = 0.5; sin(x)'
等效于:
scc 'double x = 0.5; cout << sin(x) << endl;'
如果最后一个(且仅可能)statement-expression未用分号终止,则将其发送到std::cout
。 我的问题是关于从C ++代码片段中解析出最后一个语句。 我很清楚C ++解析有多困难。 通过查找last ';'
解析带有简单sed脚本的last语句 最初对我来说足够好。 但是现在项目比小型个人项目还要大,我需要一个更好的解析器。
以下是我当前的SED解析器的微型单元测试。 您可以看到我用来进行解析的SED正则表达式:
cat <<EOF | sed 's/$//;s/[ \t]*$//;s/\(.*[;}]\)*\([^;}]\+$\)/\0 ==>> \1 PRINT(\2);/'
print
no-print;
OK; print
OK; no-print;
OK; no-print; print
FAIL; while(a){b;} no-print
FAIL; while(a) no-print
OK; for(a;b;c) {no-print}
FAIL; for(a;b;c) no-print
OK; {}
OK; {no-print-code-block;}
FAIL; print_rvalue_t{1}
FAIL; f(int{1})
FAIL; f(";")
FAIL; f(';')
FAIL; f("}")
EOF
cat
-line之后的第一行是空行。 第二行是一个空格行。 第三-陈述不以';'
结尾 -应打印。 4-2句摘要。 等等。 如果FAIL
,解析器将在此行失败。 输出看起来像这样:
print ==>> PRINT(print);
no-print;
OK; print ==>> OK; PRINT( print);
OK; no-print;
OK; no-print; print ==>> OK; no-print; PRINT( print);
FAIL; while(a){b;} print ==>> OK; while(a){b;} PRINT( no-print);
FAIL; while(a) no-print ==>> FAIL; PRINT( while(a) no-print);
OK; for(a;b;c) {no-print}
FAIL; for(a;b;c) no-print ==>> FAIL; for(a;b; PRINT(c) no-print);
OK; {}
OK; {no-print-code-block;}
FAIL; print_rvalue_t{1}
FAIL; f(int{1}) ==>> FAIL; f(int{1} PRINT());
FAIL; f(";") ==>> FAIL; f("; PRINT("));
FAIL; f(';') ==>> FAIL; f('; PRINT('));
FAIL; f("}") ==>> FAIL; f("} PRINT("));
没有==>>
标记的行是不经过修改就通过解析器的行。 在标记转换后的代码段中,最后一条语句包装在PRINT( )
。 如您所见,当前的SED解析器不是很好。
因此,我正在寻找更好的东西。 即使解析不是100%正确,我也会接受答案。 更好的SED脚本对我来说已经足够了。 正确的方法可能是使用真实的解析器(例如CLANG之类的东西),但我对此工作的复杂性有些担心。
我试图在boost / xpressive- http ://github.com/lvv/scc/blob/master/sccpp.h中编写一个解析器。 当然不是真正的C ++解析器。 这只是针对一件事的快速破解:解析出最后一条语句。 它能够执行以上所有单元测试。 但不幸的是,对于较长的摘要,它的速度令人难以忍受。
问题是:如何做出更好的解析器?
正确的方法可能是使用真正的解析器(例如CLANG之类的东西),但是我有点担心这种工作的复杂性
不太高 。 一个简单的事实是C ++就像HTML一样-您需要一个真正的库来做它,因此,除非您想花费数年时间开发自己的库,否则唯一的方法就是使用现有的C ++解析器。 在这方面,Clang是唯一的选择。 因此,无论您发现它多么复杂,您别无选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.