ghc-lexer
Memo
Haskell の文字列を字句解析した結果がわかる
ちょっと使いづらいけど、問題はない
ファイルからの読み込み、言語拡張にも対応している
インストール方法
stack
λ git clone https://github.com/carymrobbins/ghc-lexer.git
λ cd ghc-lexer
λ stack install
使い方
プログラムの終了は q
、quit
、exit
のどれかを打ち込むだけ。
lex モード
Enter を押す度に字句解析が実行される。入力の完了は <EOF>
という文字列で判定。
λ ghc-lexer
> lex
> INPUT: (Enter code to parse. Use "<EOF>" on a line to signal end of file.)
if True then 0 else 1
<EOF>
OUTPUT: (Press enter for next element. Anything else will stop lexing)
{"token":{"ITif":[]},"srcSpan":[[1,1],[1,3]]}
{"token":{"ITconid":"True"},"srcSpan":[[1,4],[1,8]]}
{"token":{"ITthen":[]},"srcSpan":[[1,9],[1,13]]}
{"token":{"ITinteger":[{"SourceText":"0"},0]},"srcSpan":[[1,14],[1,15]]}
{"token":{"ITelse":[]},"srcSpan":[[1,16],[1,20]]}
{"token":{"ITinteger":[{"SourceText":"1"},1]},"srcSpan":[[1,21],[1,22]]}
{"token":{"ITeof":[]},"srcSpan":[[2,1],[2,1]]}
lexall
わざわざ Enter を押し続けるのが面倒な人はこっち
λ ghc-lexer
> lexall
INPUT: (Enter code to parse. Use "<EOF>" on a line to signal end of file.)
if True then 0 else 1
<EOF>
{"token":{"ITif":[]},"srcSpan":[[1,1],[1,3]]}
{"token":{"ITconid":"True"},"srcSpan":[[1,4],[1,8]]}
{"token":{"ITthen":[]},"srcSpan":[[1,9],[1,13]]}
{"token":{"ITinteger":[{"SourceText":"0"},0]},"srcSpan":[[1,14],[1,15]]}
{"token":{"ITelse":[]},"srcSpan":[[1,16],[1,20]]}
{"token":{"ITinteger":[{"SourceText":"1"},1]},"srcSpan":[[1,21],[1,22]]}
{"token":{"ITvarsym":"<"},"srcSpan":[[1,22],[1,23]]}
{"token":{"ITconid":"EOF"},"srcSpan":[[1,23],[1,26]]}
{"token":{"ITvarsym":">"},"srcSpan":[[1,26],[1,27]]}
{"token":{"ITeof":[]},"srcSpan":[[3,1],[3,1]]}
ファイルから読み込む方法
lex
、lexall
モードのどちらでも使える。単純に引数にダブルクォートかシングルクォートで囲ったパスを渡すだけ。
module Main where
import qualified Language.Haskell.GHC.Parser.Main as M
main :: IO ()
main = M.main
λ ghc-lexer
> lexall "Sample.hs"
{"token":{"ITmodule":[]},"srcSpan":[[1,1],[1,7]]}
{"token":{"ITconid":"Main"},"srcSpan":[[1,8],[1,12]]}
{"token":{"ITwhere":[]},"srcSpan":[[1,13],[1,18]]}
{"token":{"ITvocurly":[]},"srcSpan":[[3,1],[3,1]]}
{"token":{"ITimport":[]},"srcSpan":[[3,1],[3,7]]}
{"token":{"ITqualified":[]},"srcSpan":[[3,8],[3,17]]}
{"token":{"ITqconid":["Language.Haskell.GHC.Parser","Main"]},"srcSpan":[[3,18],[3,50]]}
{"token":{"ITas":[]},"srcSpan":[[3,51],[3,53]]}
{"token":{"ITconid":"M"},"srcSpan":[[3,54],[3,55]]}
{"token":{"ITsemi":[]},"srcSpan":[[5,1],[5,1]]}
{"token":{"ITvarid":"main"},"srcSpan":[[5,1],[5,5]]}
{"token":{"ITdcolon":"NormalSyntax"},"srcSpan":[[5,6],[5,8]]}
{"token":{"ITconid":"IO"},"srcSpan":[[5,9],[5,11]]}
{"token":{"IToparen":[]},"srcSpan":[[5,12],[5,13]]}
{"token":{"ITcparen":[]},"srcSpan":[[5,13],[5,14]]}
{"token":{"ITsemi":[]},"srcSpan":[[6,1],[6,1]]}
{"token":{"ITvarid":"main"},"srcSpan":[[6,1],[6,5]]}
{"token":{"ITequal":[]},"srcSpan":[[6,6],[6,7]]}
{"token":{"ITqvarid":["M","main"]},"srcSpan":[[6,8],[6,14]]}
{"token":{"ITsemi":[]},"srcSpan":[[7,1],[7,1]]}
{"token":{"ITeof":[]},"srcSpan":[[7,1],[7,1]]}
参考リソース
Last updated