2024/05/24 パーサを書くときの知見
パーサを書く時の知見
ログの出力機構を丁寧に作る
再帰下降をする際は、再帰深さに応じてインデントが掘れるようにする
命名、型付けを丁寧にする
トークンの種類
失敗例
1. トークンの種類を表す文字列(TokenKindName)を定義
2. tokenize用の関数からは、TokenKindNameの配列を返すように実装
結果
Identifier(識別子)の名前を保持できない構造になり、パースの際に破綻したt6o_o6t.icon
ループして使うものは生のオブジェクトにしない
失敗例
演算子と、演算子に紐づける記号をtokenPatternsというオブジェクトに定義t6o_o6t.icon
code:tokenPatterns.ts
const tokenPatterns = {
LeftParen: "(",
RightParen: ")",
And: "∧",
Or: "∨",
Not: "¬",
Implication: "→",
} as const;
結果
実際に入力文字列の先頭と各記号の比較処理を行う段になったとき、tokenPatternsに対するfor-inループを書いた
for-inではキーの型がただのstringになってしまった
本来はより制約の厳しい、keyof typeof tokenPatternsになってほしかった
tokenize、パースに失敗した場合の処理方法を事前に考える
TypeScriptで、失敗時にnullを返しながら呼び出し元にさかのぼるコードを書いたが、毎回nullチェックを居れるのがしんどかったt6o_o6t.icon
t6o_o6t.icon
「parseをする」の目的は何か
Astを得ること
「parseをする」に必要なものは何か
トークン列(または文字列)
より狭く考えると、その時点と次の時点だけトークンを読み取ることができるインターフェース
いまt6o_o6t.iconが作っている言語?では先読みが必要ない
「中置演算子のparseをする」に必要なものは何か
左辺と右辺のExpressionをparseした結果
括弧のexpect and next
次トークンを取得しようとしたとき、Nullだと困る
何とかEOFが返ってきてほしい
パーサがトークンを最後までconsumeしなかったときに例外を出すのも良いと思うt6o_o6t.icon
JavaScriptで、パース失敗時に都度nullを返すようにするとコードが甚だしく長大になってしまう
nullを返さず例外を出すのも選択の一つになる