typescript-parsec
lexerとparserが別になっている
すべてfunction baseで設計されているっぽい?
examine defined combinators & parsrs
code:ts-parsects
interface Parser<TKind, TResult> {
parse(token?: Token<TKind>): ParserOutput<TKind, TResult>;
}
combinatorsの種類を見る上で不要なので転記しない
parsers
nil: <T>() => Parser<T, undefined>
なにもしない
文字消費なし(consumes no token)
succ: <T, R>(value: R) => Parser<T, R>
valueを返す
文字消費なし
fail (msg: string) => FailedParser
常に失敗する
文字消費なし
str: <T>(s: string) => Parser<T, Token<T>>
sにマッチする
tok: <T>(s: T) => Parser<T, Token<T>>
sにマッチする
strのtoken版
combinators
*_scつきは、最初にマッチしたparserの結果のみ返す
ついてないものは、断りがない限り、すべてのparsersを試行し、マッチした結果を結果候補としてすべて返す
and系
seq
and相当
函数overloadで2~16個のparserまで受け取れるようにしてある
とんでもないhard codingだtakker.icon
TKindはすべて同じでなければならない
combine: <T, R1, R2>(p: Parser<T, R1>, fn1: (v: R1) => Parser<T, R2>) => Parser<T, R2>
pが成功したら、その結果を使って新しいparserを作る
choice相当
型の設計はseqと同じ
fnは1~16個まで指定できるようになっている
複数指定すると、前のfnで作ったparserが成功した時、その結果が次のfnに渡される
kleft: <T, R1, R2>(p1: Parser<T, R1>, p2: Parser<T, R2>) => Parser<T, R1>
seq(p1, p2)を実行し、成功時p1の結果だけ返す
skip相当
kmid: <T, R1, R2, R3>(p1: Parser<T, R1>, p2: Parser<T, R2>, p3: Parser<T, R3>) => Parser<T, R2>
seq(p1, p2, p3)を実行し、成功時p2の結果だけ返す
wrap相当
kright: <T, R1, R2>(p1: Parser<T, R1>, p2: Parser<T, R2>) => Parser<T, R2>
seq(p1, p2)を実行し、成功時p2の結果だけ返す
next相当
or系
alt
or相当だが、すべてのparsersを試行し、成功したものをすべて返す
型の設計はseqと同じ
alt_sc
or相当
最初に成功したparserの結果のみ返す
opt_sc: <T, R>(p: Parser<T, R>) =>Parser<T, R | undefined>
optional相当
成功してもしなくてもいいparser
opt: <T, R>(p: Parser<T, R>) =>Parser<T, R | undefined>
alt(opt(p), nil)と同等
opt_scとほぼ同じだが、成功した時Rとundefinedの両方を返す
repeatitive
rep_sc: <T, R>(p: Parser<T, R>) => Parser<T, R[]>
0回以上の繰り返し
rep: <T, R>(p: Parser<T, R>) => Parser<T, R[]>
0回以上の繰り返し
3回成功したときは、[r1, r2, r3],[r1, r2],[r1],[]の順に結果を複数返す
repr
0回以上の繰り返し
3回成功したときは、[], [r1],[r1, r2],[r1, r2, r3]の順に結果を複数返す
rep_n
n回ちょうどの繰り返し
list, list_sc, list_n
dで区切った繰り返し
それぞれの違いは、rep, rep_sc, rep_nの違いと対応する
recursive
lrec: <T, R, F extends R, S>(p: Parser<T, F>, q: Parser<T, S>, fn: (a: R, b: S) => R) => Parser<T, R>
pのあとにqを繰り返し並べてparseし、結果をfnで再帰的に変換する
lrec_sc
lrecとほぼ同じ
amb: <T, R>(p: Parser<T, R>) => Parser<T, R[]>
altにおける、計算効率とメモリ効率を改善するためのcombinator
errors
err: <T, R>(p: Parser<T, R>, msg: string) => Parser<T, R>
失敗したときのmessageをmsgに変える
errd: <T, R>(p: Parser<T, R>, msg: string, d: R) => Parser<T, R>
errと同じだが、失敗した時dをdefault valueとして返す
apply: <T, R1, R2>(p: Parser<T, R1>, fn: (v: R1) => R2) => Parser<T, R2>
parserのTResultを変換する
map相当