Comments 5
Это конечно не «нормальный» парсер, особенно в сравнении по скорости, но для своих нужд писал парсер в две функции.
изначально работал чуть медленно, добавил мемоизацию и всё стало ok.
изначально работал чуть медленно, добавил мемоизацию и всё стало ok.
Открыть
Разбор происходит прямо в код, описав типы и подобное дерево вызовов:
Не особо по статье, но может кому пригодится такой легковесный парсер.
p_and ((t:ts),f) vi vs s i m c =
case M.lookup (t,i) c of
Just v ->
case v of
Left (m,i1,s1) -> p_and (ts,f) (i1+vi) (s1:vs) s (i+i1) (max m (i + i1)) c
Right i2 -> N i2 c
Nothing ->
case call t s i m c of
P m i1 s1 c -> p_and (ts,f) (i1+vi) (s1:vs) s (i+i1) (max m (i + i1)) (M.insert (t,i) (Left (m,i1,s1)) c)
N i2 c -> N (max m i2) (M.insert (t,i) (Right i2) c)
p_and ([],f) vi vs s i m c =
P m vi (f (reverse vs)) c
p_or (o:os) s i m c =
case p_and o 0 [] s i m c of
P m i s c -> P m i s c
N i2 c -> p_or os s i (max i2 m) c
p_or [] s i m c =
N (max i m) c
Разбор происходит прямо в код, описав типы и подобное дерево вызовов:
call Tletters =
p_or [
([Tletter, Tletters], \(Sc n i:Ss n2 _:[]) -> Ss (n:n2) i)
,([Tletter], \(Sc n i:[]) -> Ss (n:"") i)
]
call Tvar =
p_or [
([Tletters,Tnum_pos], \(Ss s i:Sn n _:[]) -> Ss (s++show n) i)
,([Tletters], \(Ss s i:[]) -> Ss s i)
]
Не особо по статье, но может кому пригодится такой легковесный парсер.
+4
А всякие yacc(bison) и lex уже отменили?
+4
тягу к знаниям уже отменили?
+2
При чем тут тяга к знаниям? От подобных постов создается впечатление, что во-первых, у автора появилась академическая осведомленность о процессе разбора грамматики (что похвально), во-вторых проявилось желание изобрести n+1-й велосипед. Что полезно для личностного роста, но выкатывать это велосипед в паблик — скорее вредно, ибо захламляет эфир.
+1
Парсеры отлично писать на Rxx (Extensions for Reactive extensions). Там внизу есть много ссылок о том как описывать парсеры с помощью монад (в синтаксисе LINQ).
0
Sign up to leave a comment.
Написание парсера с нуля: так ли страшен черт?