"simple" C++ 解析器
"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;'
若最后一个(也是可能的唯一一个)语句表达式并没有以分号结束,它将被发送到std::cout
。我的问题是从C++代码片段中解析出最后一个语句。我很清楚C++解析有多困难。用简单的sed脚本解析最后一条语句,只需查找最后一个';'
,对我来说一开始就足够了。但现在这个项目比个人的小项目更大,我需要一个更好的解析器。
下面是我当前SED解析器的小型单元测试。您可以看到我用来进行解析的SED正则表达式:
cat <<EOF | sed 's/$//;s/[ t]*$//;s/(.*[;}])*([^;}]+$)/ ==>> 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
-行之后的第一行为空行。第二行是一条空行。第3条-未以';'
终止的声明-应打印。第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/expressive编写一个解析器http://github.com/lvv/scc/blob/master/sccpp.h。当然不是真的C++解析器。这只是一个快速破解,只为一件事:解析出最后一条语句。是的能够完成以上所有单元测试。但不幸的是,对于较长的片段来说慢得令人无法忍受。
问题是:如何制作一个更好的解析器?
正确的方法可能是使用真正的解析器(来自有点像CLANG),但我有点担心复杂性
不过高。简单的事实是,C++就像HTML一样——你需要一个真正的库来完成它,所以除非你想花数年时间开发自己的库,否则几乎唯一的方法就是使用现有的C++解析器。Clang是这方面的唯一选择。因此,无论你觉得它多么复杂,你都别无选择。
- 为什么别名声明不是有效的 init 语句(/simple-declaration)?
- SImple 代码在 DevC++ 中正确运行,但不能在 Visual Studio Code 中正常运行
- 使用 clang 和 G++ 编译此"simple"程序时出现链接错误
- "simple" C++ 解析器
- C++ - Simple SharedQueue 是必需的
- 我们是否需要为分配"placement new" "simple POD classes"显式调用析构函数?
- 以"simple c++"模式编译的程序在从QtCreator启动时不起作用
- C Simple RingBuffer语言 - 多线程 - 查找关键部分
- Simple auto_ptr
- Simple C++ getter/setters
- CMake "clang++ is not able compile a simple test program" (Fedora 20)
- 使用Rvalue引用和Simple Factory
- C++ - Noob - Simple Try/Catch
- C++ Simple cout ostream
- C++查找和替换字符串SIMPLE
- const integer simple
- 与C++ "simple"符号和符号的计算混淆
- 非类-name c++ 11类型-name是一个simple-template-id
- 使用Arduino Mega和Simple-H高压电机屏蔽控制直流电机
- 如何在没有邮件客户端的情况下使用Simple MAPI