Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gargantext-ihaskell
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
gargantext-ihaskell
Commits
73791d37
Commit
73791d37
authored
Jun 25, 2016
by
Andrew Gibiansky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Attempt to fix quasiquotes parsing bug with a hack
parent
94338f8d
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
54 additions
and
2 deletions
+54
-2
Parser.hs
ghc-parser/generic-src/Language/Haskell/GHC/Parser.hs
+43
-2
Parser.hs
src/tests/IHaskell/Test/Parser.hs
+11
-0
No files found.
ghc-parser/generic-src/Language/Haskell/GHC/Parser.hs
View file @
73791d37
...
...
@@ -23,7 +23,8 @@ module Language.Haskell.GHC.Parser (
layoutChunks
,
)
where
import
Data.List
(
intercalate
,
findIndex
)
import
Data.List
(
intercalate
,
findIndex
,
isInfixOf
)
import
Data.Char
(
isAlphaNum
)
import
Bag
import
ErrUtils
hiding
(
ErrMsg
)
...
...
@@ -131,8 +132,10 @@ joinLines = intercalate "\n"
-- A chunk is a line and all lines immediately following that are indented
-- beyond the indentation of the first line. This parses Haskell layout
-- rules properly, and allows using multiline expressions via indentation.
--
-- Quasiquotes are allowed via a post-processing step.
layoutChunks
::
String
->
[
Located
String
]
layoutChunks
=
go
1
layoutChunks
=
joinQuasiquotes
.
go
1
where
go
::
LineNumber
->
String
->
[
Located
String
]
go
line
=
filter
(
not
.
null
.
unloc
)
.
map
(
fmap
strip
)
.
layoutLines
line
.
lines
...
...
@@ -174,6 +177,7 @@ layoutChunks = go 1
indentLevel
_
=
0
-- | Drop comments from Haskell source.
-- Simply gets rid of them, does not replace them in any way.
removeComments
::
String
->
String
...
...
@@ -240,3 +244,40 @@ removeComments = removeOneLineComments . removeMultilineComments 0 0
'"'
:
rest
->
"
\"
"
x
:
xs
->
x
:
takeString
xs
[]
->
[]
-- | Post processing step to combine quasiquoted blocks into single blocks.
-- This is necessary because quasiquoted blocks don't follow normal indentation rules.
joinQuasiquotes
::
[
Located
String
]
->
[
Located
String
]
joinQuasiquotes
=
reverse
.
joinQuasiquotes'
.
reverse
where
-- This operates by finding |] and then joining blocks until a line
-- that has some corresponding [...|. This is still a hack, but close to
-- good enough.
joinQuasiquotes'
[]
=
[]
joinQuasiquotes'
(
block
:
blocks
)
=
if
"|]"
`
isInfixOf
`
unloc
block
then
let
(
pieces
,
rest
)
=
break
(
hasQuasiquoteStart
.
unloc
)
blocks
in
case
rest
of
[]
->
block
:
joinQuasiquotes'
blocks
startBlock
:
blocks'
->
concatBlocks
(
block
:
pieces
++
[
startBlock
])
:
joinQuasiquotes
blocks'
else
block
:
joinQuasiquotes'
blocks
-- Combine a lit of reversed blocks into a single, non-reversed block.
concatBlocks
::
[
Located
String
]
->
Located
String
concatBlocks
blocks
=
Located
(
line
$
last
blocks
)
$
joinLines
$
map
unloc
$
reverse
blocks
-- Does this string have a [...| in it?
hasQuasiquoteStart
::
String
->
Bool
hasQuasiquoteStart
str
=
case
break
(
==
'['
)
str
of
(
_
,
""
)
->
False
(
_
,
_
:
rest
)
->
case
break
(
==
'|'
)
rest
of
(
_
,
""
)
->
False
(
chars
,
_
)
->
all
isIdentChar
chars
isIdentChar
::
Char
->
Bool
isIdentChar
c
=
isAlphaNum
c
||
c
==
'_'
||
c
==
'
\'
'
src/tests/IHaskell/Test/Parser.hs
View file @
73791d37
...
...
@@ -66,6 +66,17 @@ testLayoutChunks = describe "Layout Chunk" $ do
,
Located
5
"third"
,
Located
7
"fourth"
]
it
"deals with quasiquotes"
$
do
let
parsesAsBlocks
strs
=
map
unloc
(
layoutChunks
$
unlines
strs
)
`
shouldBe
`
strs
parsesAsBlocks
[
"let x = [q|a quasiquote|]"
]
parsesAsBlocks
[
"let x = [q|a quasiquote|]"
,
"3"
]
parsesAsBlocks
[
"let x = [q|a quasiquote
\n
|]"
]
parsesAsBlocks
[
"let x = [q|
\n
a quasiquote
\n
|]"
]
parsesAsBlocks
[
"let x =
\"
[q|doesn't matter
\"
"
]
parsesAsBlocks
[
"[q|q<-[1..10]]"
]
parsesAsBlocks
[
"[q|x|] [q|x|]"
]
parsesAsBlocks
[
"[q|
\n
x
\n
|] [q|x|]"
]
testModuleNames
::
Spec
testModuleNames
=
describe
"Get Module Name"
$
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment