{
{-# LANGUAGE OverloadedStrings #-}
module Language.Virgil.Parser where
import Language.Virgil.AST
import Language.Virgil.Lexer
}
%name parse
%tokentype { Token }
%monad { Alex }
%lexer { lexwrap } { Token _ TkEOF }
%error { happyError }
%token
'{' { Token _ TkLCurl }
'}' { Token _ TkRCurl }
'[' { Token _ TkLBrac }
']' { Token _ TkRBrac }
':' { Token _ TkColon }
';' { Token _ TkSemi }
',' { Token _ TkComma }
with { Token _ (TkKw KwWith) }
true { Token _ (TkKw KwTrue) }
false { Token _ (TkKw KwFalse) }
null { Token _ (TkKw KwNull) }
int { Token _ (TkInt $$) }
float { Token _ (TkFloat $$) }
str { Token _ (TkStr $$) }
%%
tlexpr
: '[' list { mkArray $2 }
| '{' dict { mkObject $2 }
scalar
: int { ChNumber (fromIntegral $1) }
| float { ChNumber $1 }
| str { ChString $1 }
| true { ChBool True }
| false { ChBool False}
| null { ChNull }
expr
: tlexpr { $1 }
| scalar { $1 }
list
: ']' { [] }
| expr ']' { [ $1 ] }
| expr ',' list { $1 : $3 }
dict
: '}' { [] }
| str ':' expr '}' { [ ($1, $3) ] }
| str ':' expr ',' dict { ($1, $3) : $5 }
{
-- info :: a -> Alex (Info a)
-- info x = do
-- (AlexPn _ ln cl,_,_,_) <- alexGetInput
-- fp <- getFilePath
-- return $ Info { node = x
-- , srcLine = ln
-- , srcCol = cl
-- , srcFile = fp
-- }
lexwrap :: (Token -> Alex a) -> Alex a
lexwrap = (alexMonadScan' >>=)
happyError :: Token -> Alex a
happyError (Token p t) =
alexError' p ("parse error at token " ++ show t)
parseFile :: FilePath -> String -> Either String ChValue
parseFile = runAlex' parse
}