Что хотел спросить.

Sep 25, 2006 01:49

Давным-давно я написал статью по разборщики на потоковых процессорах.

Так вот, работают они совершенно нелинейно. Простой разборщик наподобие \n -> prun (pmany (ptoken '1' `ppar` ptoken '2')) (replicate n '1') работает за квадратичное от n время.

Есть у меня подозрение, что это из-за того, что ppar реализован не как исключающий ppar монадных ( Read more... )

потоковые процессоры, haskell, разборщики

Leave a comment

parser rvp74 September 28 2006, 20:31:02 UTC
Глянул твой pseq и решил переписать все с нуля ;)

data SP a b = NullSP | Put b (SP a b) | Get (a -> SP a b)

failSP = NullSP

returnSP a = Put a NullSP

seqSP NullSP f = NullSP
seqSP (Get h) f = Get $ \a -> seqSP (h a) f
seqSP (Put b spa) f = f b `parSP` seqSP spa f

parSP :: SP a b -> SP a b -> SP a b
parSP NullSP spb = spb
parSP spa NullSP = spa
parSP (Put b spa) spb = Put b $ parSP spa spb
parSP spa (Put b spb) = Put b $ parSP spa spb
parSP (Get fa) (Get fb) = Get $ \a -> parSP (fa a) (fb a)

mapSP f NullSP = NullSP
mapSP f (Get g) = Get $ \a -> mapSP f (g a)
mapSP f (Put b sp) = Put (f b) (mapSP f sp)

instance Monad (SP a) where
return = returnSP
(>>=) = seqSP
fail _ = failSP

instance Functor (SP a) where
fmap = mapSP

readInput = Get $ returnSP

char c = do
a <- readInput ( ... )

Reply

Re: parser thesz September 28 2006, 20:46:51 UTC
С чего бы это она отбрасывается?

Нисколечки она не отбрасывается.

Рассинхронизации не произойдет, поскольку мы сперва выдадим все возможные на данный момент результаты, а затем запросим вход.

Вообще, потоковые процессоры мне нравятся. Только я их дальше разборщиков не освоил. ;)

Reply

Re: parser rvp74 September 28 2006, 21:08:41 UTC
В семантику <|> не должна входить выдача результа альтернативы до момента отказа первой альтернативы. Не путай с par

Reply

Re: parser thesz September 28 2006, 23:17:58 UTC
О! Его реализации у тебя нет. Понял.

Reply

Re: parser rvp74 September 29 2006, 09:50:50 UTC
Само собой нету. Требования <|> соблюсти проблематично при синхронизированном вводе и/или отсутствии просмотра наперед без чтения (lookAHead) и возврата символов во входной поток (setInput). Максимум что можно сделать сейчас это соблюсти первых три закона. Это даст некий бонус за счет отбрасывания второй альтернативы при наличии вывода в первой альтернативе.

Reply

Re: parser thesz September 29 2006, 11:15:42 UTC
Зато мы останавливаемся там, где ошибка. И легко сделать 2D синтаксис без порчи кода основной грамматики.

Reply

Re: parser rvp74 September 29 2006, 12:41:08 UTC
В общем я придумал как сделать altSP (ака <|>)

Где-то так:

altSP NullSP spb = spb
altSP spa NullSP = spa
altSP spa@(Put _ _) _ = spa
altSP (Get fa) (Get fb) = Get $ \a -> parSP (fa a) (fb a)
altSP (Get fa) spb = Get $ \a -> fa a `altSP` bufInput a spb

bufInput a NullSP = NullSP
bufInput a (Get f) = f a
bufInput a (Put b spb) = Put b $ bufInput a spb

Все хорошо, но есть один маленький недостаток - не работает. :)

пробовал на:

option s p = p `altSP` return s

test = parseSP (option '_' (char '1') >> char '2') "2 "

выдает почему-то пустой список

Reply

Re: parser thesz September 29 2006, 13:17:06 UTC
Нельзя всегда отбрасывать возвращаемое второй альтернативой значение.

Я сделал вот так:
altSP NullSP spb = spb
altSP spa NullSP = spa
altSP spa@(Put _ _) _ = spa
altSP (Get fa) (Get fb) = Get $ \a -> parSP (fa a) (fb a)
altSP a@(Get fa) (Put o b) = Put o $ altSP a bи оно заработало. ;)

Reply

Re: parser rvp74 September 29 2006, 13:31:26 UTC
Этот вариант неинтересен (потому как кидает второй вариант до отказа первого).
Кстати, там у меня опечатка (которая осталась и в твоем коде: вместо altSP написанно parSP)

Reply

Re: parser rvp74 September 29 2006, 13:33:50 UTC
Я отбрасываю альтернативу только в одном случае - если первая успешна

Reply


Leave a comment

Up