tree-sitter-haskell
Haskell grammar for tree-sitter.
References
Building with nvim-treesitter
When installing the grammar from source, be sure to include the scanner in the source files:
lua <<EOF
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
parser_config.haskell = {
install_info = {
url = "~/path/to/tree-sitter-haskell",
files = {"src/parser.c", "src/scanner.c", "src/unicode.h"}
}
}
EOF
Supported Language Extensions
These extensions are supported β , unsupported β or not applicable because they don't involve parsing βοΈ:
- AllowAmbiguousTypes βοΈ
- ApplicativeDo βοΈ
- Arrows β
- BangPatterns β
- BinaryLiterals β
- BlockArguments β
- CApiFFI β
- ConstrainedClassMethods β
- ConstraintKinds β
- CPP β
- CUSKs β
- DataKinds β
- DatatypeContexts β
- DefaultSignatures β
- DeriveAnyClass βοΈ
- DeriveDataTypeable βοΈ
- DeriveFoldable βοΈ
- DeriveFunctor βοΈ
- DeriveGeneric βοΈ
- DeriveLift βοΈ
- DeriveTraversable βοΈ
- DerivingStrategies β
- DerivingVia β
- DisambiguateRecordFields βοΈ
- DuplicateRecordFields βοΈ
- EmptyCase β
- EmptyDataDecls β
- EmptyDataDeriving β
- ExistentialQuantification β
- ExplicitForAll β
- ExplicitNamespaces β
- ExtendedDefaultRules βοΈ
- FlexibleContexts β
- FlexibleInstances β
- ForeignFunctionInterface β
- FunctionalDependencies β
- GADTs β
- GADTSyntax β
- GeneralisedNewtypeDeriving βοΈ
- GHCForeignImportPrim β
- Haskell2010 βοΈ
- Haskell98 βοΈ
- HexFloatLiterals β
- ImplicitParams β
- ImplicitPrelude βοΈ
- ImportQualifiedPost β
- ImpredicativeTypes βοΈ
- IncoherentInstances βοΈ
- InstanceSigs β
- InterruptibleFFI β
- KindSignatures β
- LambdaCase β
- LexicalNegation β
- LiberalTypeSynonyms β
- LinearTypes β
- MagicHash β
- Modifiers β
- MonadComprehensions βοΈ
- MonadFailDesugaring βοΈ
- MonoLocalBinds βοΈ
- MonomorphismRestriction βοΈ
- MultiParamTypeClasses β
- MultiWayIf β
- NamedFieldPuns β
- NamedWildCards β
- NegativeLiterals βοΈ
- NondecreasingIndentation β
- NPlusKPatterns βοΈ
- NullaryTypeClasses β
- NumDecimals βοΈ
- NumericUnderscores β
- OverlappingInstances βοΈ
- OverloadedLabels β
- OverloadedLists βοΈ
- OverloadedRecordDot β
- OverloadedRecordUpdate β
- OverloadedStrings βοΈ
- PackageImports β
- ParallelListComp β
- PartialTypeSignatures β
- PatternGuards β
- PatternSynonyms β
- PolyKinds βοΈ
- PostfixOperators βοΈ
- QualifiedDo β
- QuantifiedConstraints β
- QuasiQuotes β
- Rank2Types β
- RankNTypes β
- RebindableSyntax βοΈ
- RecordWildCards βοΈ
- RecursiveDo β
- RoleAnnotations β
- Safe βοΈ
- ScopedTypeVariables β
- StandaloneDeriving β
- StandaloneKindSignatures β
- StarIsType β
- StaticPointers β
- Strict βοΈ
- StrictData β
- TemplateHaskell β
- TemplateHaskellQuotes β
- TraditionalRecordSyntax βοΈ
- TransformListComp β
- Trustworthy βοΈ
- TupleSections β
- TypeApplications β
- TypeData β
- TypeFamilies β
- TypeFamilyDependencies β
- TypeInType β
- TypeOperators β
- TypeSynonymInstances βοΈ
- UnboxedSums β
- UnboxedTuples β
- UndecidableInstances βοΈ
- UndecidableSuperClasses βοΈ
- UnicodeSyntax β
- UnliftedFFITypes βοΈ
- UnliftedNewtypes β
- Unsafe βοΈ
- ViewPatterns β
Bugs
CPP
Preprocessor #elif
and #else
directives cannot be handled correctly, since the parser state would have to be
manually reset to what it was at the #if
.
As a workaround, the code blocks in the alternative branches are parsed as part of the directives.
Layout
NondecreasingIndentation
is not supported (yet?).
do
Operators on newlines in A strange edge case is when an infix operator follows an expression statement of a do block with an indent of less or equal the do
's layout column:
f = do
readSomething
>>= doSomething
The >>=
causes the do
's layout to be terminated, resulting in an AST similar to
f = (do readSomething) >>= doSomething
This is checked heuristically, probably unreliably.
Testing
Requires: tree-sitter(-cli)
Run test corpus
These are stored in ./tests/corpus/
$ tree-sitter test
Test parsing an example codebase
Requires: bc
This will print the percentage of the codebase parsed, and the time taken
$ ./script/parse-examples # this clones all repos
$ ./script/parse-example <example> # where <example> is a project under ./examples/
Enable scanner debug output
To get an extra-verbose scanner, unoptimized, with debug symbols:
$ CFLAGS='-DDEBUG' make debug.so
$ cp debug.so $HOME/.cache/tree-sitter/lib/haskell.so # So `tree-sitter-cli` uses our binary
$ tree-sitter test
$ ./script/parse-example <example>
If you want to debug the scanner with gdb
, you can
b tree_sitter_haskell_external_scanner_scan
with tree-sitter test
.
Create visual graph of parser steps
Requires: graphviz
$ tree-sitter parse -D test/Basic.hs # Produces log.html