use ielr::input::{Grammar, Node, Symbol, Token};
const START: Node = Node(0);
const STATEMENTS: Node = Node(1);
const STATEMENT: Node = Node(2);
const FUNCTION: Node = Node(3);
const FUNCTION_ARGS: Node = Node(4);
const FUNCTION_ARG: Node = Node(5);
const EXPRESSION: Node = Node(6);
const ARGS: Node = Node(7);
const fn new_token(t: u16) -> Token {
match Token::new(t) {
Some(t) => t,
None => unreachable!(),
}
}
const RETURN_KW: Token = new_token(1);
const LET_KW: Token = new_token(2);
const IDENT: Token = new_token(3);
const SEMICOLON: Token = new_token(4);
const EQUAL: Token = new_token(5);
const FN_KW: Token = new_token(6);
const PARENTHESIS_LEFT: Token = new_token(7);
const PARENTHESIS_RIGHT: Token = new_token(8);
const BRACE_LEFT: Token = new_token(9);
const BRACE_RIGHT: Token = new_token(10);
const COMMA: Token = new_token(11);
const INT: Token = new_token(12);
const PLUS: Token = new_token(13);
const MINUS: Token = new_token(14);
const STAR: Token = new_token(15);
const SLASH: Token = new_token(16);
fn main() {
use Symbol::{Node as N, Token as T};
let mut grammar = Grammar::new();
for (lhs, rhs) in [
(START, vec![N(STATEMENTS)]),
(STATEMENTS, vec![N(STATEMENT), N(STATEMENTS)]),
(STATEMENTS, vec![]),
(STATEMENT, vec![N(FUNCTION)]),
(STATEMENT, vec![T(RETURN_KW), N(EXPRESSION), T(SEMICOLON)]),
(
STATEMENT,
vec![T(LET_KW), T(IDENT), T(EQUAL), N(EXPRESSION), T(SEMICOLON)],
),
(STATEMENT, vec![N(EXPRESSION), T(SEMICOLON)]),
(
FUNCTION,
vec![
T(FN_KW),
T(IDENT),
T(PARENTHESIS_LEFT),
N(FUNCTION_ARGS),
T(PARENTHESIS_RIGHT),
T(BRACE_LEFT),
N(STATEMENTS),
T(BRACE_RIGHT),
],
),
(
FUNCTION_ARGS,
vec![N(FUNCTION_ARG), T(COMMA), N(FUNCTION_ARGS)],
),
(FUNCTION_ARGS, vec![N(FUNCTION_ARG)]),
(FUNCTION_ARGS, vec![]),
(FUNCTION_ARG, vec![T(IDENT)]),
(EXPRESSION, vec![T(INT)]),
(EXPRESSION, vec![T(IDENT)]),
(ARGS, vec![N(EXPRESSION), T(COMMA), N(ARGS)]),
(ARGS, vec![N(EXPRESSION)]),
(ARGS, vec![]),
] {
grammar.add_production(lhs, rhs).unwrap();
}
let precedence_family = grammar.add_precedence_family();
for (lhs, rhs, left, right) in [
(
EXPRESSION,
vec![N(EXPRESSION), T(PLUS), N(EXPRESSION)],
Some(1),
Some(2),
),
(
EXPRESSION,
vec![N(EXPRESSION), T(MINUS), N(EXPRESSION)],
Some(1),
Some(2),
),
(
EXPRESSION,
vec![N(EXPRESSION), T(STAR), N(EXPRESSION)],
Some(3),
Some(4),
),
(
EXPRESSION,
vec![N(EXPRESSION), T(SLASH), N(EXPRESSION)],
Some(3),
Some(4),
),
(EXPRESSION, vec![T(MINUS), N(EXPRESSION)], None, Some(5)),
] {
let production = grammar.add_production(lhs, rhs).unwrap();
let production = grammar.get_production_mut(production).unwrap();
if let Some(left) = left {
production.set_left_precedence(precedence_family, left);
}
if let Some(right) = right {
production.set_right_precedence(precedence_family, right);
}
}
let (_tables, _statistics) = ielr::compute_table(
ielr::Algorithm::Lalr(std::num::NonZeroU8::new(1).unwrap()),
&grammar,
[START],
)
.unwrap();
}