Skip to content

Instantly share code, notes, and snippets.

@qguv
Last active May 3, 2017 16:16
Show Gist options
  • Save qguv/e612ff96291121cac6a8 to your computer and use it in GitHub Desktop.
Save qguv/e612ff96291121cac6a8 to your computer and use it in GitHub Desktop.
(*
An EBNF Grammar of Gee
Quint Guvernator for CSCI 312-01, Spring 2015
Using the ISO/IEC 14977 standard of the EBNF metalanguage
Features of ISO 14977:
- non-terminal symbols can be multiword
- RHS is a sequence of tokens separated by commas
- comments
*)
(* High-level Syntax *)
program = sequence, [ Eoln ];
sequence = statement, { Eoln, statement };
statement = imperative | flow control;
(* Imperative statements *)
imperative = assignment | function application;
assignment = Identifier, Define, expression;
function application =
Identifier, Open, [ expression, { Comma, expression } ], Close;
(* Control flow *)
flow control = if block, while block;
if block = if clause, [ else clause ];
if clause = If, test with clause;
else clause = Else, test with clause;
while block = While, test with clause;
test with clause =
expression, Colon, Eoln, Indent, sequence, Eoln, Undent;
(* Expressions *)
expression = composable, { compose operator, composable };
composable = comparable, { compare operator, comparable };
comparable = term, { term operator, term };
term = factor, { factor operator, factor };
factor = ([ unary operator ], operand) | (Open, expression, Close);
operand = literal | Identifier;
literal = IntLiteral | StringLiteral;
(* Terminal symbols. I'm capitalizing these for clarity. *)
Open = "(";
Close = ")";
Comma = ",";
Define = "=";
Colon = ":";
While = "while";
If = "if";
unary operator =
Bang | Tilde;
Bang = "!";
Tilde = "~";
term operator =
Plus | Minus;
Plus = "+";
Minus = "-";
factor operator =
Asterisk | Solidus;
Asterisk = "*";
Solidus = "/";
compare operator =
Greater | Less | GreaterEq | LessEq | Is | Isnt;
Greater = ">";
Less = "<";
GreaterEq = ">=";
LessEq = "<=";
Is = "==";
Isnt = "!=";
compose operator =
And | Or;
And = "&&";
Or = "||";
(* From the lexer *)
Identifier = "Identifier";
IntLiteral = "IntLiteral";
StringLiteral = "StringLiteral";
Indent = "Indent";
Undent = "Undent";
Eoln = "Eoln";
(* vim: se syntax=ebnf: *)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment