Skip to content

Instantly share code, notes, and snippets.

@DmitrySoshnikov
Last active June 16, 2017 04:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DmitrySoshnikov/e05057acb30b03436e833ff41a77f3c7 to your computer and use it in GitHub Desktop.
Save DmitrySoshnikov/e05057acb30b03436e833ff41a77f3c7 to your computer and use it in GitHub Desktop.
/**
* Calculator grammar to generate parser in Rust.
*/
%lex
%%
// -----------------------------------------------
// Lexical grammar.
//
// Uses regexp to produce list of tokens.
// Return values is a token type.
\s+ /* skip whitespace */ return "";
\d+ return "NUMBER";
"+" return "+";
"*" return "*";
"(" return "(";
")" return ")";
/lex
// -----------------------------------------------
// Operator precedence.
//
// The `*` goes after `+`, so it has higher precedence,
// and `2 + 2 * 2` is correctly parsed as `2 + (2 * 2)`.
//
// Also both are left-associative, meaning
// `2 + 2 + 2` is `(2 + 2) + 2`, which is important
// when we build AST nodes.
%left +
%left *
// -----------------------------------------------
// Module include.
//
// The code which is included "as is" to the generated
// parser. Should at least contain `TResult` -- the
// type of the final parsed value.
%{
// Important: define the type of the parsing result:
type TResult = i32;
%}
%%
// -----------------------------------------------
// Syntactic grammar (BNF).
//
// Defines an actual syntactic structure of
// our program.
Expr
// ---------------------------------------
// Addition
: Expr + Expr {
// Types of used args, and the return type.
|$1: i32, $3: i32| -> i32;
$$ = $1 + $3
}
// ---------------------------------------
// Multiplication
| Expr * Expr {
|$1: i32, $3: i32| -> i32;
$$ = $1 * $3
}
// ---------------------------------------
// Simple number
| NUMBER {
|| -> i32;
$$ = yytext.parse::<i32>().unwrap()
}
// ---------------------------------------
// Grouping in parens
| ( Expr ) {
$$ = $2
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment