# A grammar for an imaginary but pretty programming language a bit like Python. # ----------------------------------------------------------------------------- # A comment. It is useful to define this non-terminal both as an abbreviation # and also so that I can write optional and/or repeated comments. c ::= { Some {COMMENT} } # The non-terminals 'expr0' to 'expr5' represent the grammar of expressions. The # number (0 to 5) represents the tightness of binding of the permitted # operators. Specifically, 'expr0' includes any operator no matter how loosely # it binds, 'expr1' does not permit comparisons, 'expr2' does not permit # additions and subtractions, 'expr3' does not permit multiplications and # divisions, 'expr4' does not permit negations and 'expr5' permits no operators # at all, not even function calls. expr5 ::= { Number {NUMBER} String {STRING} Variable {IDENTIFIER} Bracket {ROUND(expr0)} } call ::= { Some {ROUND(paramList?)} } expr4 ::= { Some {expr5 call*} } sign ::= {Some {"-"} } expr3 ::= { Some {sign* expr4}} op2 ::= { Mul {"*"} Div {"/"} } tail2 ::= { Some {op2 expr3} } expr2 ::= { Some {expr3 tail2*} } op1 ::= { Add {"+"} Sub {"-"} } tail1 ::= { Some {op1 expr2} } expr1 ::= { Some {expr2 tail1*} } op0 ::= { Lt {"<"} Eq {"="} Le {"<="} Gt {">"} Ne {"<>"} Ge {">="} } tail0 ::= { Some {op0 expr1} } expr0 ::= { Some {expr1 tail0*} } # Comma-separated lists of expressions, used for function calls. paramComma ::= { Some {expr0 ","} } paramList ::= { Some {paramComma* expr0} } # Comma-separated lists of identifiers, used for function definitions. argComma ::= { Some {IDENTIFIER ","} } argList ::= { Some {argComma* IDENTIFIER}} # "ELSE" clause, used for "IF" and "WHILE" statements. else ::= {Some {"ELSE" BRACE(cStatement*)} } # Imperative statements. statement ::= { Call {expr5 call+} Assignment {IDENTIFIER "=" expr0} Definition {"DEF" IDENTIFIER ROUND(argList?) BRACE(cStatement*)} If {"IF" ROUND(expr0) BRACE(cStatement*) else?} While {"WHILE" ROUND(expr0) BRACE(cStatement*) else?} Break {"BREAK"} Return {"RETURN" expr0} } # A statement optionally preceded by comments. cStatement ::= { Some {c* statement} } # A linker symbol. symbol ::= { Some {CONSTANT} } # A top-level declaration. At the top level "IMPORT" and "EXPORT" declarations # are allowed in addition to normal statements. declaration ::= { Statement {c* statement} Export {c* "EXPORT" expr0 "AS" symbol+} Import {c* "IMPORT" symbol+ "AS" IDENTIFIER} } ROOT declaration*