csv-parser / src / CSVQLGrammar.y
CSVQLGrammar.y
Raw
{ 
module CSVQLGrammar where
import CSVQLTokens
}

%name parseCalc
%tokentype { Token }
%error { parseError }
%token 
    int     { TokenInt _ $$ }
    str     { TokenString _ $$ }
    true    { TokenTrue _ }
    false   { TokenFalse _ }
    null    { TokenNull _ }
    and     { TokenAnd _ }
    or      { TokenOr _}
    for     { TokenFor _ }
    in      { TokenIn _ }
    if      { TokenIf _ }
    else    { TokenElse _ }
    '{'     { TokenLCurly _ }
    '}'     { TokenRCurly _ }
    '.'     { TokenDot _ }
    ';'     { TokenSemi _ }
    '='     { TokenEq _ }
    '+'     { TokenPlus _ }
    "=="    { TokenEqq _ }
    not     { TokenNot _ }
    '('     { TokenLParen _ }
    ')'     { TokenRParen _ }
    '['     { TokenSquareL _ }
    ']'     { TokenSquareR _ }
    ','     { TokenComma _ }
    var     { TokenVar _ $$ }
    '<'     { TokenLess _ }
    '>'     { TokenGreater _ }

%left and or
%% 

E : E2 ';' E                        { Semi $1 $3 }
  | E1                              { $1 }

E1 : E2 ';'                         { $1 }
   | E2                             { $1 }

E2 : var '=' E3                     { Assign $1 $3 }
   | E3                             { $1 }

E3 : E3 and E3                      { And $1 $3 }
   | E3 or E3                       { Or $1 $3 }
   | E33                            { $1 }

E33 : not E4                        { Not $2 }
    | E4                            { $1 }

E4 : E6 "==" E4                     { Equals $1 $3 }
   | E6 '<' E4                      { LessThan $1 $3 }
   | E6 '>' E4                      { GreaterThan $1 $3 }
   | E5                             { $1 }

E5 : E6 ',' E5                      { ListBody $1 $3 }
   | E6                             { $1 }

E6 : '[' E5 ']'                     { List $2 }
   | E7                             { $1 }

E7 : E7 '[' E8 ']'                  { Index $1 $3 }
   | E8                             { $1 }

E8 : E9 '+' E8                      { Plus $1 $3 }
   | E9                             { $1 }

E9 : var '.' var '(' E3 ')'          { Sub $1 $3 $5 }
   | var '(' E3 ')'                  { Func $1 $3 }
   | for var in var '{' E '}'       { For $2 $4 $6 }
   | if E '{' E '}'                 { If $2 $4 }
   | if E '{' E '}' else '{' E '}'  { IfElse $2 $4 $8 }
   | E10                            { $1 }

E10 : int                           { Int $1 }
    | str                           { String $1 }
    | false                         { Bool False }
    | true                          { Bool True }
    | null                          { Null }
    | var                           { Var $1 }
    | '(' E5 ')'                    { $2 }

{
parseError :: [Token] -> a
parseError [] = error "Parse Error"
parseError (t: _) = error $ "Parse error at " ++ tokenPosn t

data E = For String String E
        | Int Int
        | String String
        | Semi E E
        | Sub String String E
        | Func String E
        | ListBody E E
        | Var String
        | Assign String E
        | If E E
        | IfElse E E E
        | Equals E E
        | Bool Bool
        | List E
        | Plus E E
        | Null
        | Row E
        | Table E E
        | Not E
        | Index E E
        | And E E
        | Or E E
        | LessThan E E
        | GreaterThan E E
         deriving (Eq, Show)
}