# 084: litpatternb.hs で parseError: TInteger (0,AlexPn 24 2 3) [↑up](bunny_notes) - issued: 2020-05-18 - 分類: A サンプルコードが fail - status: Closed (2021-11-06) ## 概要 以下のようなプログラム (litpatternb.hs) をコンパイルすると、Parse Error となる。 $$
{ f x = case x of 0 -> "zero" _ -> "non-zero" main = do putStrLn $ f 1 putStrLn $ f 0 $$} つぎのように変換してやればいい(以下のプログラムは現状でも通る)。 $${ f x = case x of x | x == 0 -> "zero" _ -> "non-zero" main = do putStrLn $ f 1 putStrLn $ f 0 $$} ## 調査ログ ### 2020-10-26 変換に際して、すこし気になったので、${x | x == a -> hoge} が複数生じるケースを追加 (litpetternc2.hs) $$ { f x = case x of x | x == 0 -> "zero" x | x == 1 -> "one" _ -> "other" main = do print $ f 0 print $ f 1 print $ f 2 $$} これがちゃんと通るので、大丈夫そう。 だが、現状のエラーは、この式変換以前に、Parse Error になっている。Parser.y をみてみなければ。 ## 2020-12-28 とりあえずコンパイルしてみる。 $${ $ bunny tcompile litpatternb.hs /home/unno/bunny/0.9.0/bin/bunnyc -d ./jout/litpatternb --xno-implicit-prelude /home/unno/bunny/0.9.0/lib/Prelude.hs /home/unno/bunny/0.9.0/bin/bunnyc -d ./jout/litpatternb --xlibrary-path /home/unno/bunny/0.9.0/lib -v litpatternb.hs implicitPrelude ... done. Error: parseError: TInteger (0,AlexPn 24 2 3) $$} ## 2021-10-24 全件確認シリーズ: $${ unno@unno-FMVD70GN7G ~/work/bissues/084 $ cat litpatternb.hs f x = case x of 0 -> "zero" _ -> "non-zero" main = do putStrLn $ f 1 putStrLn $ f 0 unno@unno-FMVD70GN7G ~/work/bissues/084 $ runhaskell litpatternb.hs non-zero zero unno@unno-FMVD70GN7G ~/work/bissues/084 $ ~/prj/bunny/compiler/bin/bunny tcompile litpatternb.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb --xno-implicit-prelude /home/unno/prj/bunny/compiler/bin/../lib/Prelude.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb --xlibrary-path /home/unno/prj/bunny/compiler/bin/../lib -v litpatternb.hs implicitPrelude ... done. Error: parseError: TInteger (0,AlexPn 24 2 3) $$} これと似てるが、リテラルじゃなくてリストにマッチさせるようなのもあって、 そちらも現状は parse error: $${ unno@unno-FMVD70GN7G ~/work/bissues/084 $ cat litpatternbX.hs f x = case x of 'X' -> "X" _ -> "not X" main = do putStrLn $ f 'X' putStrLn $ f 'Y' unno@unno-FMVD70GN7G ~/work/bissues/084 $ runhaskell litpatternbX.hs X not X unno@unno-FMVD70GN7G ~/work/bissues/084 $ ~/prj/bunny/compiler/bin/bunny tcompile litpatternbX.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternbX --xno-implicit-prelude /home/unno/prj/bunny/compiler/bin/../lib/Prelude.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternbX --xlibrary-path /home/unno/prj/bunny/compiler/bin/../lib -v litpatternbX.hs implicitPrelude ... done. Error: parseError: TChar ('X',AlexPn 24 2 3) $$} ## 2021-11-03 文法をみなおしても、これが文法エラーになるようには見えない。 また、GHC の Parser.y.source の対応する部分と見比べても、とくに変なところがない。 もしかして、文法エラー以外にも (semantic action で例外をなげるなどで) parseError になる場合があるのかというめで Parser.y をみると、vcurly の対応がとれない場合なんかにそうなるみたい。 では、というので、レイアウト規則を使わないように libpatternb.hs を書き換えてみたら、通った! $${ unno@unno-FMVD70GN7G ~/work/bissues/084 $ cat litpatternb_curly.hs f x = case x of { 0 -> "zero"; _ -> "non-zero" } main = do putStrLn $ f 1 putStrLn $ f 0 unno@unno-FMVD70GN7G ~/work/bissues/084 $ ~/prj/bunny/compiler/bin/bunny testrun litpatternb_curly.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb_curly --xno-implicit-prelude /home/unno/prj/bunny/compiler/bin/../lib/Prelude.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb_curly --xlibrary-path /home/unno/prj/bunny/compiler/bin/../lib litpatternb_curly.hs non-zero zero $$} 被疑箇所はレイアウト規則の処理だったもよう。 ## 2021-11-06 $${ unno@unno-FMVD70GN7G ~/work/bissues/084 $ cat litpatternb3.hs f x = case x of 0.0 -> "zero" _ -> "non-zero" main = do putStrLn $ f (1.0::Double) putStrLn $ f (0.0::Float) $ runhaskell litpatternb3.hs non-zero zero unno@unno-FMVD70GN7G ~/work/bissues/084 $ ghci litpatternb3.hs GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Main ( litpatternb3.hs, interpreted ) Ok, one module loaded. *Main> :t f f :: (Eq a, Fractional a) => a -> [Char] *Main> :q Leaving GHCi. unno@unno-FMVD70GN7G ~/work/bissues/084 $ ~/prj/bunny/compiler/bin/bunny tcompile --ddump-assump litpatternb3.hs |& less /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb3 --xno-implicit-prelude /home/unno/prj/bunny/compiler/bin/../lib/Prelude.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb3 --xlibrary-path /home/unno/prj/bunny/compiler/bin/../lib -v --ddump-assump litpatternb3.hs implicitPrelude ... done. Error: parseError: TFloat (0.0,AlexPn 24 2 3) $$} TFloat も act_token を介すように変更しなくてはいけない。以下のとおり変更: $${ $ git diff diff --git a/compiler/src/Lexer.x b/compiler/src/Lexer.x index adfb4b0..231f96c 100644 --- a/compiler/src/Lexer.x +++ b/compiler/src/Lexer.x @@ -533,7 +533,7 @@ act_integer (pos, _, _, s) len = act_token (TInteger (i, pos)) pos i = read $ take len s act_float :: AlexAction Token -act_float (pos, _, _, s) len = do unFlags; return $ TFloat (x, pos) +act_float (pos, _, _, s) len = do act_token (TFloat (x, pos)) pos where x = read $ take len s } $$} コンパイル通るようになり、Main.f の型もただしい(GHC のときと同じ)ようだ: $${ /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb3 --xno-implicit-prelude /home/unno/prj/bunny/compiler/bin/../lib/Prelude.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb3 --xlibrary-path /home/unno/prj/bunny/compiler/bin/../lib -v --ddump-assump litpatternb3.hs implicitPrelude ... done. doCompile ... Debugging dump of assumptions (results of the type inference). #overloaded# :: (a -> ([Prelude.Char] -> b)) Main.f :: Forall [Star] ([Prelude.Fractional a] :=> (a -> [Prelude.Char])) $$} 実行結果: $${ $ ~/prj/bunny/compiler/bin/bunny testrun litpatternb3.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb3 --xno-implicit-prelude /home/unno/prj/bunny/compiler/bin/../lib/Prelude.hs /home/unno/prj/bunny/compiler/bin/bunnyc -d ./jout/litpatternb3 --xlibrary-path /home/unno/prj/bunny/compiler/bin/../lib litpatternb3.hs non-zero zero $$} これで、いちおう、本 issue はクローズかな。テストにいくつか加えよう。sample334-337