ManagedX 有 5 種訪問修飾符(public, protected, private, internal, protected internal),前四者為單 Token,最後一個為 Tuple。需默認 private。舊組合子寫法冗長且需多個輔助函數。
def 與 letdef(pattern, defaultValue):匹配成功返回 pattern 結果,失敗返回 defaultValue。let(pattern, value):匹配成功返回 value,失敗則整體失敗。組合使用,消除輔助函數:
// 舊寫法:需 ToAccessor, ToProtectedInternal, ToAccessorWithDefault 三個函數
accessor = (PUBLIC[ToAccessor] | PROTECTED[ToAccessor] | PRIVATE[ToAccessor] | INTERNAL[ToAccessor] | (PROTECTED+INTERNAL)[ToProtectedInternal])[ToAccessorWithDefault];
// 新寫法:一行搞定
accessor = def(
let(PUBLIC, acc::Public) |
let(PROTECTED, acc::Protected) |
let(PRIVATE, acc::Private) |
let(INTERNAL, acc::Internal) |
let(PROTECTED+INTERNAL, acc::ProtectedInternal),
acc::Private // 默認值
);
binop 解決表達式性能瓶頸通用 lrec 處理帶括號表達式時,每層括號增加一層文法遞歸。ManagedX 有 10+ 優先級,復雜表達式全加括號會導致數千層遞歸,虛函數調用開銷大。
binop 設計手寫優先級解析器,通過流式 API 定義運算符表:
expression = binop(exp0)
.pre(ADD_SUB, ToPreUnary).pre(NOT_BITNOT, ToPreUnary).pre(INC_DEC, ToPreUnary).precedence()
.lbin(MUL_DIV_MOD, ToBinary).precedence()
.lbin(ADD_SUB, ToBinary).precedence()
.lbin(LT|LT, ToBinaryShift).lbin(GT|GT, ToBinaryShift).precedence()
.lbin(LT, ToBinary).lbin(LE, ToBinary).lbin(GT, ToBinary).lbin(GE, ToBinary).precedence()
.post(AS+type, ToCasting).post(IS+type, ToIsType).precedence()
.lbin(EE, ToBinary).lbin(NE, ToBinary).precedence()
.lbin(BITAND, ToBinary).precedence()
.lbin(XOR, ToBinary).precedence()
.lbin(BITOR, ToBinary).precedence()
.lbin(AND, ToBinary).precedence()
.lbin(OR, ToBinary).precedence()
.lbin(QQ, ToNullChoice).precedence()
.lbin(QT+(expression<
pre:前綴一元運算符(-a, ++i)。post:後綴一元運算符(i++)。lbin:左結合二元運算符(a+b+c)。rbin:右結合二元運算符(a=b=c)。precedence():分隔優先級層級。lrec 寫法exp1 = exp0 | ((ADD_SUB | NOT_BITNOT | INC_DEC) + exp1)[ToUnary];
exp2 = lrec(exp1 + *((MUL_DIV_MOD + exp1)[ToBinaryLrec]), ToLrecExpression);
exp3 = lrec(exp2 + *((ADD_SUB + exp2)[ToBinaryLrec]), ToLrecExpression);
// ... 每層優先級一個 lrec
def/let 簡化「可選匹配 + 默認值」模式,binop 以手寫優先級解析器替代通用左遞歸,解決了「括號炸彈」性能問題。Parser Combinator 重獲實用性能,同時保持極快編譯速度與聲明式風格。