Cake > 設計
todo
インデックスカウンタ追加
エラー時のパース続行
continue する間の子要素を保存?
until に skip を指定した時に無限再帰?
コンセプト
強力で幅広い機能
汎用性
多言語 / 環境対応
利用場面
コンパイラでのソースコード解析
ソースコード埋め込みによる文字列解析? (正規表現のような使い方)
名前: Pega, Nez, Cake
処理系
パーサベイカ
パーサジェネレータ
構成要素
パッケージ
モジュール
規則
code:構文
div := Symbol::division;
Expression {
pub mod All
// All と Expression で重複した規則名を使うと警告
* := Expression;
pub bionominal := Bionominal;
end
Bionominal {
}
pub add := Expression div "+" div Expression;
}
規則定義
code:規則定義
rule := Expression "..." | _*;
rule
// define the same rules as the other module.
// like tuple expansion
pub {expand_1, expand_2} := from Module;
table:表現字句
モジュール名? 特定モジュール内のいずれかの規則 (選択的)
規則名 特定の規則
table:構文一覧
モジュール定義 m { r; ... }
選択 e1 | e2
連接 e1 e2
規則 name := e
引数付き規則 name(a1, a2) := e
繰り返し e? e* e+ e{n-m}
グループ化 (e1 e2)
手順
Gen: ソースコード → 最適化→ 中間データ
共通: 中間データ → 最適化 → パース
code:generator.ches
let gen = mut Generator::new();
gen.maxRecursion = 10000;
let m_main = mut Module::new();
gen.add_module(m_main);
CakeIL
内部 ID (連番)
グローバル ID
内部 ID 4バイト
種類 1バイト
付加情報
値長 2バイト
値 可変長
先読み 3ビット
フラグ 4バイト
メモ
数字範囲のマッチ
先頭などのマッチ
ジェネレータ: 規則パース時にユーザが記述したプログラムを噛ませられる?
ベイク: 異なる言語間の共有, パースデータの分離
separator 追加
テクニック, 注意点など
() でグループ化できるとは限らない ×
包含要素が 1 つの場合, (e + e) + e (e | e) | e のパターン
group() によるグループ化と括弧の省略 (可読性のため括弧の省略を推奨)
単体テストケース
表現生成関数
正常な生成とパニック発生
構文木
子要素取り出し等の各種操作
パース関数
関数ごとの入力と出力
結合テストケース
表現生成〜パース結果照合までの流れ