BPL Grammar
%nonassoc IFX
%nonassoc ELSE
%right "="
%nonassoc LETBODY
%right "?"
%right CONS
%left &
%right AND OR
%left < gt; LE GE EQ NE
%left "+" "-"
%left "*" "/" "%"
%nonassoc UMINUS "!" TYPEOF CAR CDR
%left "(" "[" "."
%%
program: imports blockStmnts
imports:
| imports "import" importName ";"
importName: IDENT
| importName "." IDENT
blockStmnts: blockStmnt
| blockStmnts blockStmnt
blockStmnt: "var" varDecls ";"
| "varrec" varDecls ";"
| "$$" sdefines "$$"
| stmnt
varDecls: varDecl
| varDecls "," varDecl
varDecl: IDENT
| IDENT "=" expr
stmnt: if
| loop
| "break" ";"
| "break" IDENT ";"
| "continue" ";"
| "continue" IDENT ";"
| "return" seqexpr ";"
| "{" blockStmnts "}"
| seqexpr ";"
| ";"
if: "if" "(" seqexpr ")" stmnt %prec IFX
| "if" "(" seqexpr ")" stmnt "else" stmnt
loop: optlabel "while" "(" seqexpr ")" stmnt
| optlabel "for" "(" optseqexpr ";" optseqexpr ";" optseqexpr ")" stmnt
optlabel:
| IDENT ":"
optseqexpr:
| seqexpr
seqexpr: expr
| expr "," expr
expr: expr "&&" expr
| expr "||" expr
| expr ">" expr
| expr "<" expr
| expr "<=" expr
| expr ">=" expr
| expr "==" expr
| expr "!=" expr
| expr "+" expr
| expr "-" expr
| expr "*" expr
| expr "/" expr
| expr "%" expr
| expr "&" expr
| "-" expr %prec UMINUS
| "!" expr %prec '!'
| "typeof" expr %prec TYPEOF
| expr "?" expr ":" expr %prec '?'
| "(" seqexpr ")"
| IDENT
| IDENT "=" expr
| get
| get "=" expr
| literal
| lambda
| expr "(" exprs ")"
| "{" keyValues "}"
| "[" exprs "]"
| let
| "$" sexpr "$"
get: expr "[" seqexpr "]"
| expr "." IDENT
literal: INTEGER
| STRING
| "true"
| "false"
| "null"
lambda: "lambda" "(" idents optelipsis ")" "{" blockStmnts "}"
idents:
| idents1
idents1: IDENT
| idents1 "," IDENT
optelipsis:
| "..."
exprs:
| exprs1
exprs1: expr
| exprs1 "," expr
keyValues:
| keyValues1
keyValues1: keyValue
| keyValues1 "," keyValue
keyValue: IDENT ":" expr
let: "let" "{" letBindings "}" expr %prec LETBODY
| "letrec" "{" letBindings "}" expr %prec LETBODY
letBindings: letBinding
| letBindings "," letBinding
letBinding: IDENT "=" expr
sdefines: sdefine
| sdefines sdefine
sdefine: "(" "define" IDENT sexpr ")"
| "(" "define" "(" IDENT sidents ")" slambody ")"
| "(" "define" "(" IDENT sidents "." IDENT ")" slambody ")"
sexpr: IDENT
| "(" "set" IDENT sexpr ")"
| sif
| literal
| slambda
| "(" sexpr sexprs ")"
| slet
| "(" "cond" scondbody ")"
| "(" "&&" sandbody ")"
| "(" "||" sorbody ")"
| "(" "begin" sbeginbody ")"
| "(" "quote" sdatum ")"
| "'" sdatum
| "$" expr "$"
sif: "(" "if" sexpr sexpr ")"
| "(" "if" sexpr sexpr sexpr ")"
slambda: "(" "lambda" "(" sidents ")" slambody ")"
| "(" "lambda" IDENT slambody ")"
| "(" "lambda" "(" sidents "." IDENT ")" slambody ")"
sidents:
| sidents IDENT
slambody: sexprs sexpr
sexprs:
| sexprs sexpr
slet: "(" "let" "(" sletbindings ")" sexpr ")"
| "(" "letrec" "(" sletbindings ")" sexpr ")"
| "(" "let"_STAR "(" sletbindings ")" sexpr ")"
sletbindings:
| sletbindings "(" IDENT sexpr ")"
scondbody: "(" sexpr sexpr ")"
| "(" "else" sexpr ")"
| "(" sexpr sexpr ")" scondbody
sandbody: sexpr
| sexpr sandbody
sorbody: sexpr
| sexpr sorbody
sbeginbody: sexpr
| sbeginbody sexpr
sdatums: sdatum
| sdatum "." sdatum
| sdatum sdatums
sdatum: literal
| IDENT
| "(" ")"
| "(" sdatums ")"