支援:+ - * /、括號、負號、單參數函數(sin, cos 等)。
示例:sin(1+2) + cos(3*-4)
RULE = EXPRESSION
DIGIT = '0' | '1' | ... | '9'
INTEGER = DIGIT | INTEGER DIGIT // 遞歸定義整數
FACTOR = INTEGER | '(' EXPRESSION ')' | FUNCTION
FUNCTION = IDENTIFIER '(' EXPRESSION ')'
TERM = FACTOR | TERM ('*' | '/') FACTOR
EXPRESSION = TERM | EXPRESSION ('+' | '-') TERM
關鍵點:左遞歸對應左結合運算符;| 表示選擇;IDENTIFIER 由詞法層識別。
Token,標記類型(INTEGER, PLUS, SIN 等)。RegexTokenReader 正則匹配生成 Token 流。Parser 組合子(seq, alt, rep 等)構建遞歸下降解析器。Expr 基類及 BinaryOp, FunctionCall, Number 等子類。// Token 定義
enum TokenType { TK_INT, TK_PLUS, TK_MINUS, TK_MUL, TK_DIV, TK_LPAREN, TK_RPAREN, TK_SIN, TK_COS, TK_ID };
// 詞法分析
auto lexer = RegexTokenReader()
.add(L"\\d+", TK_INT)
.add(L"\\+", TK_PLUS)
.add(L"\\-", TK_MINUS)
.add(L"\\*", TK_MUL)
.add(L"/", TK_DIV)
.add(L"\\(", TK_LPAREN)
.add(L"\\)", TK_RPAREN)
.add(L"sin", TK_SIN)
.add(L"cos", TK_COS)
.add(L"[a-zA-Z_]\\w*", TK_ID);
// 語法組合子
auto factor = alt(
token(TK_INT)[make_number],
seq(token(TK_LPAREN), expression, token(TK_RPAREN))[make_paren],
seq(token(TK_SIN), token(TK_LPAREN), expression, token(TK_RPAREN))[make_sin],
seq(token(TK_COS), token(TK_LPAREN), expression, token(TK_RPAREN))[make_cos]
);
auto term = lrec(factor, alt(
seq(token(TK_MUL), factor)[make_mul],
seq(token(TK_DIV), factor)[make_div]
));
auto expression = lrec(term, alt(
seq(token(TK_PLUS), term)[make_add],
seq(token(TK_MINUS), term)[make_sub]
));
lrec解決左結合運算符(如 a-b-c = (a-b)-c)的遞歸下降解析問題。
lrec(base, op_rules) 內部將左遞歸轉為迭代,生成左傾 AST。
ExpressionCalculator.sln
├── Lexer.h/cpp // 詞法分析
├── Parser.h/cpp // 語法分析 + AST 構建
├── Evaluator.h/cpp // AST 求值
└── main.cpp // REPL 循環
Vczh Library++ 以組合子風格讓語法分析器開發變得聲明式、模組化。從「定義語法」到「生成可執行代碼」全流程可控,適合構建配置語言、腳本引擎、查詢解析器等 DSL 場景。