on master help sign in
Be more aggressive with parsing reserved words
commitbf46a33016ed76738c36537ab8fe1b4a239a3724 authorEvan Czaplicki <info@elm-lang.org> dateTue 16 Dec 2014, 14:57 (12 years ago) parent1461bf7
5 files changed+122−77
src/Parse/Declaration.hs+33−23 src/Parse/Expression.hs+72−40 src/Parse/Helpers.hs+4−2 src/Parse/Module.hs+3−7 src/Parse/Pattern.hs+10−5
src/Parse/Declaration.hs+33−23
@@ -21,29 +21,32 @@ definition = D.Definition <$> Expr.def
2121
2222typeDecl :: IParser D.SourceDecl
2323typeDecl =
24− do reserved "type" <?> "type declaration"
25− forcedWS
26− isAlias <- optionMaybe (string "alias" >> forcedWS)
24+ do try (reserved "type") <?> "type declaration"
25+ forcedWS
26+ isAlias <- optionMaybe (string "alias" >> forcedWS)
2727
28− name <- capVar
29− args <- spacePrefix lowVar
30− padded equals
28+ name <- capVar
29+ args <- spacePrefix lowVar
30+ padded equals
3131
32− case isAlias of
33− Just _ ->
34− do tipe <- Type.expr <?> "a type"
35− return (D.TypeAlias name args tipe)
32+ case isAlias of
33+ Just _ ->
34+ do tipe <- Type.expr <?> "a type"
35+ return (D.TypeAlias name args tipe)
3636
37− Nothing ->
38− do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
39− return $ D.Datatype name args tcs
37+ Nothing ->
38+ do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
39+ return $ D.Datatype name args tcs
4040
4141
4242infixDecl :: IParser D.SourceDecl
4343infixDecl = do
44− assoc <- choice [ reserved "infixl" >> return D.L
45− , reserved "infix" >> return D.N
46− , reserved "infixr" >> return D.R ]
44+ assoc <-
45+ choice
46+ [ try (reserved "infixl") >> return D.L
47+ , try (reserved "infixr") >> return D.R
48+ , try (reserved "infix") >> return D.N
49+ ]
4750 forcedWS
4851 n <- digit
4952 forcedWS
@@ -52,10 +55,17 @@ infixDecl = do
5255
5356port :: IParser D.SourceDecl
5457port =
55− do try (reserved "port")
56− whitespace
57− name <- lowVar
58− whitespace
59− let port' op ctor expr = do { try op ; whitespace ; ctor name <$> expr }
60− D.Port <$> choice [ port' hasType D.PPAnnotation Type.expr
61− , port' equals D.PPDef Expr.expr ]
58+ do try (reserved "port")
59+ whitespace
60+ name <- lowVar
61+ whitespace
62+ let port' op ctor expr =
63+ do try op
64+ whitespace
65+ ctor name <$> expr
66+
67+ D.Port <$>
68+ choice
69+ [ port' hasType D.PPAnnotation Type.expr
70+ , port' equals D.PPDef Expr.expr
71+ ]
src/Parse/Expression.hs+72−40
@@ -139,56 +139,87 @@ appExpr = do
139139-------- Normal Expressions --------
140140
141141binaryExpr :: IParser Source.Expr
142−binaryExpr = Binop.binops appExpr lastExpr anyOp
143− where lastExpr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
144− <|> lambdaExpr
142+binaryExpr =
143+ Binop.binops appExpr lastExpr anyOp
144+ where
145+ lastExpr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
146+ <|> lambdaExpr
147+
145148
146149ifExpr :: IParser Source.Expr'
147−ifExpr = reserved "if" >> whitespace >> (normal <|> multiIf)
148− where
149− normal = do
150− bool <- expr
151− padded (reserved "then")
152− thenBranch <- expr
153− whitespace <?> "an 'else' branch" ; reserved "else" <?> "an 'else' branch" ; whitespace
154− elseBranch <- expr
155− return $ E.MultiIf
156− [ (bool, thenBranch)
157− , (Annotation.sameAs elseBranch (E.Literal . L.Boolean $ True), elseBranch)
158− ]
159−
160− multiIf = E.MultiIf <$> spaceSep1 iff
161− where iff = do string "|" ; whitespace
162− b <- expr ; padded arrow
163− (,) b <$> expr
150+ifExpr =
151+ do try (reserved "if")
152+ whitespace
153+ normal <|> multiIf
154+ where
155+ normal = do
156+ bool <- expr
157+ padded (reserved "then")
158+ thenBranch <- expr
159+ whitespace <?> "an 'else' branch"
160+ reserved "else" <?> "an 'else' branch"
161+ whitespace
162+ elseBranch <- expr
163+ return $ E.MultiIf
164+ [ (bool, thenBranch)
165+ , (Annotation.sameAs elseBranch (E.Literal . L.Boolean $ True), elseBranch)
166+ ]
167+
168+ multiIf =
169+ E.MultiIf <$> spaceSep1 iff
170+ where
171+ iff =
172+ do string "|" ; whitespace
173+ b <- expr ; padded arrow
174+ (,) b <$> expr
175+
164176
165177lambdaExpr :: IParser Source.Expr
166−lambdaExpr = do char '\\' <|> char '\x03BB' <?> "anonymous function"
167− whitespace
168− args <- spaceSep1 Pattern.term
169− padded arrow
170− body <- expr
171− return (makeFunction args body)
178+lambdaExpr =
179+ do char '\\' <|> char '\x03BB' <?> "anonymous function"
180+ whitespace
181+ args <- spaceSep1 Pattern.term
182+ padded arrow
183+ body <- expr
184+ return (makeFunction args body)
185+
172186
173187defSet :: IParser [Source.Def]
174−defSet = block (do d <- def ; whitespace ; return d)
188+defSet =
189+ block $
190+ do d <- def
191+ whitespace
192+ return d
193+
175194
176195letExpr :: IParser Source.Expr'
177−letExpr = do
178− reserved "let" ; whitespace
179− defs <- defSet
180− padded (reserved "in")
181− E.Let defs <$> expr
196+letExpr =
197+ do try (reserved "let")
198+ whitespace
199+ defs <- defSet
200+ padded (reserved "in")
201+ E.Let defs <$> expr
202+
182203
183204caseExpr :: IParser Source.Expr'
184−caseExpr = do
185− reserved "case"; e <- padded expr; reserved "of"; whitespace
186− E.Case e <$> (with <|> without)
187− where case_ = do p <- Pattern.expr
188− padded arrow
189− (,) p <$> expr
190− with = brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
191− without = block (do c <- case_ ; whitespace ; return c)
205+caseExpr =
206+ do try (reserved "case")
207+ e <- padded expr
208+ reserved "of"
209+ whitespace
210+ E.Case e <$> (with <|> without)
211+ where
212+ case_ =
213+ do p <- Pattern.expr
214+ padded arrow
215+ (,) p <$> expr
216+
217+ with =
218+ brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
219+
220+ without =
221+ block (do c <- case_ ; whitespace ; return c)
222+
192223
193224expr :: IParser Source.Expr
194225expr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
@@ -196,6 +227,7 @@ expr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
196227 <|> binaryExpr
197228 <?> "an expression"
198229
230+
199231defStart :: IParser [P.RawPattern]
200232defStart =
201233 choice [ do p1 <- try Pattern.term
src/Parse/Helpers.hs+4−2
@@ -95,8 +95,10 @@ makeVar p =
9595
9696reserved :: String -> IParser String
9797reserved word =
98− (try (string word >> notFollowedBy innerVarChar) >> return word)
99− <?> "reserved word '" ++ word ++ "'"
98+ expecting ("reserved word '" ++ word ++ "'") $
99+ do string word
100+ notFollowedBy innerVarChar
101+ return word
100102
101103
102104-- INFIX OPERATORS
src/Parse/Module.hs+3−7
@@ -26,12 +26,8 @@ headerAndImports =
2626 do optional freshLine
2727 (names, exports) <-
2828 option (["Main"], Var.openListing) (header `followedBy` freshLine)
29− imports' <- commitToImports <|> return []
29+ imports' <- imports
3030 return $ Module.HeaderAndImports names exports imports'
31− where
32− commitToImports =
33− do try (lookAhead $ reserved "import")
34− imports `followedBy` freshLine
3531
3632
3733header :: IParser ([String], Var.Listing Var.Value)
@@ -48,12 +44,12 @@ header =
4844
4945imports :: IParser [(Module.Name, Module.ImportMethod)]
5046imports =
51− option [] ((:) <$> import' <*> many (try (freshLine >> import')))
47+ many (import' `followedBy` freshLine)
5248
5349
5450import' :: IParser (Module.Name, Module.ImportMethod)
5551import' =
56− do reserved "import"
52+ do try (reserved "import")
5753 whitespace
5854 names <- dotSep1 capVar
5955 (,) names <$> option (Module.As (intercalate "." names)) method
src/Parse/Pattern.hs+10−5
@@ -25,12 +25,17 @@ basic = choice
2525 c:_ | isUpper c -> P.Data (Var.Raw v) []
2626 _ -> P.Var v
2727
28+
2829asPattern :: P.RawPattern -> IParser P.RawPattern
29−asPattern pattern = do
30− var <- optionMaybe (try (whitespace >> reserved "as" >> whitespace >> lowVar))
31− return $ case var of
32− Just v -> P.Alias v pattern
33− Nothing -> pattern
30+asPattern pattern =
31+ do var <- optionMaybe (try (whitespace >> reserved "as") >> whitespace >> lowVar)
32+ case var of
33+ Just v ->
34+ return (P.Alias v pattern)
35+
36+ Nothing ->
37+ return pattern
38+
3439
3540record :: IParser P.RawPattern
3641record = P.Record <$> brackets (commaSep1 lowVar)