Back to BPL Home

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

// Scheme expressions

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 ")"