[英]“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.