Happy parse lex #1

Merged
msydneyslaga merged 7 commits from happy-parse-lex into main 2023-11-20 14:09:33 -07:00
3 changed files with 86 additions and 27 deletions
Showing only changes of commit 45952ef30e - Show all commits

10
src/Compiler/RLPC.hs Normal file
View File

@@ -0,0 +1,10 @@
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
module Compiler.RLPC
( RLPC(..)
)
where
-- TODO: fancy errors
newtype RLPC a = RLPC { runRLPC :: Either String a }
deriving (Functor, Applicative, Monad)

View File

@@ -4,6 +4,7 @@ module Core.Lex
( lexCore ( lexCore
, lexCore' , lexCore'
, CoreToken(..) , CoreToken(..)
, lexTmp
) )
where where
import Data.Char (chr) import Data.Char (chr)
@@ -81,7 +82,7 @@ $white_no_nl+ { skip }
"of" { constTok TokenOf `andBegin` layout_keyword } "of" { constTok TokenOf `andBegin` layout_keyword }
"case" { constTok TokenCase } "case" { constTok TokenCase }
"module" { constTok TokenModule } "module" { constTok TokenModule }
"in" { constTok TokenIn } "in" { letin }
"where" { constTok TokenWhere } "where" { constTok TokenWhere }
} }
@@ -136,10 +137,8 @@ data CoreToken = TokenLet
| TokenLitInt Int | TokenLitInt Int
| TokenVarName Name | TokenVarName Name
| TokenConName Name | TokenConName Name
| TokenName Name -- temp
| TokenVarSym Name | TokenVarSym Name
| TokenConSym Name | TokenConSym Name
| TokenSym Name -- temp
| TokenEquals | TokenEquals
| TokenLParen | TokenLParen
| TokenRParen | TokenRParen
@@ -265,17 +264,21 @@ getOffside = do
doBol :: Lexer doBol :: Lexer
doBol (p,c,_,s) l = do doBol (p,c,_,s) l = do
off <- getOffside off <- getOffside
-- traceM $ show (p, c, s)
col <- getSrcCol col <- getSrcCol
traceM $ show (s, p, col, off)
case off of case off of
LT -> insRBrace p LT -> insRBrace p
EQ -> insSemi p EQ -> insSemi p
_ -> lexToken _ -> lexToken
testTmp :: IO (Either String [CoreToken]) letin :: Lexer
testTmp = do letin (p,_,_,_) l = do
s <- readFile "/tmp/t.hs" popContext
pure $ lexCore' s pure $ Located p TokenIn
lexTmp :: IO [CoreToken]
lexTmp = do
s <- readFile "/tmp/t.hs"
case lexCore' s of
Left e -> error e
Right a -> pure a
} }

View File

@@ -1,20 +1,24 @@
-- TODO: resolve shift/reduce conflicts
{ {
module Core.Parse module Core.Parse
( parseCore ( parseCore
-- , parseCoreExpr , parseCoreExpr
, module Core.Lex -- temp convenience , module Core.Lex -- temp convenience
, parseTmp
) )
where where
import Data.Foldable (foldl') import Data.Foldable (foldl')
import Core.Syntax import Core.Syntax
import Core.Lex import Core.Lex
import Compiler.RLPC
} }
%name parseCore %name parseCore Module
%name parseCoreExpr Expr %name parseCoreExpr Expr
%tokentype { CoreToken } %tokentype { CoreToken }
%error { parseError } %error { parseError }
%monad { RLPC }
%token %token
let { TokenLet } let { TokenLet }
@@ -24,8 +28,10 @@ import Core.Lex
',' { TokenComma } ',' { TokenComma }
in { TokenIn } in { TokenIn }
litint { TokenLitInt $$ } litint { TokenLitInt $$ }
name { TokenName $$ } varname { TokenVarName $$ }
sym { TokenSym $$ } varsym { TokenVarSym $$ }
conname { TokenConName $$ }
consym { TokenConSym $$ }
'λ' { TokenLambda } 'λ' { TokenLambda }
'->' { TokenArrow } '->' { TokenArrow }
'=' { TokenEquals } '=' { TokenEquals }
@@ -34,23 +40,43 @@ import Core.Lex
'{' { TokenLBrace } '{' { TokenLBrace }
'}' { TokenRBrace } '}' { TokenRBrace }
';' { TokenSemicolon } ';' { TokenSemicolon }
eof { TokenEOF }
%% %%
ExportList :: { [Name] } Module :: { Module }
ExportList : '(' Exports ')' { $2 } Module : module conname where Program Eof { Module (Just ($2, [])) $4 }
| Program Eof { Module Nothing $1 }
Exports :: { [Name] } Eof :: { () }
Exports : Var ',' Exports { $1 : $3 } Eof : eof { () }
| Var { [$1] } | error { () }
Program :: { Program }
Program : '{' ScDefs Close { Program $2 }
ScDefs :: { [ScDef] }
ScDefs : ScDef ';' ScDefs { $1 : $3 }
| {- epsilon -} { [] }
ScDef :: { ScDef }
ScDef : Var ParList '=' Expr { ScDef $1 $2 $4 }
ParList :: { [Name] }
ParList : Var ParList { $1 : $2 }
| {- epsilon -} { [] }
Expr :: { Expr } Expr :: { Expr }
Expr : let Bindings in Expr { Let NonRec $2 $4 } Expr : let '{' Bindings Close in Expr { Let NonRec $3 $6 }
| letrec Bindings in Expr { Let Rec $2 $4 } | letrec '{' Bindings Close in Expr { Let Rec $3 $6 }
| 'λ' Binders '->' Expr { Lam $2 $4 } | 'λ' Binders '->' Expr { Lam $2 $4 }
| Application { $1 } | Application { $1 }
| Expr1 { $1 } | Expr1 { $1 }
Close :: { () }
Close : '}' { () }
| error { () }
Binders :: { [Name] } Binders :: { [Name] }
Binders : Var Binders { $1 : $2 } Binders : Var Binders { $1 : $2 }
| Var { [$1] } | Var { [$1] }
@@ -65,18 +91,38 @@ AppArgs : Expr1 AppArgs { $1 : $2 }
Expr1 :: { Expr } Expr1 :: { Expr }
Expr1 : litint { IntE $1 } Expr1 : litint { IntE $1 }
| Var { Var $1 } | Id { Var $1 }
| '(' Expr ')' { $2 } | '(' Expr ')' { $2 }
Var :: { Name }
Var : '(' sym ')' { $2 }
| name { $1 }
Bindings :: { [Binding] } Bindings :: { [Binding] }
Bindings : Var '=' Expr { [$1 := $3] } Bindings : Binding ';' Bindings { $1 : $3 }
| Binding ';' { [$1] }
| Binding { [$1] }
Binding :: { Binding }
Binding : Var '=' Expr { $1 := $3 }
Id :: { Name }
Id : Var { $1 }
| Con { $1 }
Var :: { Name }
Var : '(' varsym ')' { $2 }
| varname { $1 }
Con :: { Name }
Con : '(' consym ')' { $2 }
| conname { $1 }
{ {
parseError :: [CoreToken] -> a parseError :: [CoreToken] -> a
parseError _ = error "fuuckk!" parseError ts = error $ "parse error at token: " <> show (head ts)
parseTmp :: IO (Module)
parseTmp = do
s <- readFile "/tmp/t.hs"
case lexCore' s >>= runRLPC . parseCore of
Left e -> error e
Right a -> pure a
} }