Misc changes to make the expr-arena-ast test case work

(threading through type parameters etc)
This commit is contained in:
Niko Matsakis 2015-07-15 06:21:43 -04:00
parent 43995dd6cf
commit bfe72e14fc
16 changed files with 4158 additions and 1735 deletions

View File

@ -1,4 +1,4 @@
grammar; grammar(scale: i32);
use util::tok::Tok; use util::tok::Tok;
@ -26,7 +26,7 @@ Factor = {
Term; Term;
}; };
Term = { Term: i32 = {
<"Num">; <n:"Num"> => n * scale;
"(" <Expr> ")"; "(" <Expr> ")";
}; };

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
grammar<'ast>(arena: &'ast Arena<'ast>);
use expr_arena_ast::{Arena, Node, Op};
use util::tok::Tok;
extern token {
enum Tok {
"(" => Tok::LParen(..),
")" => Tok::RParen(..),
"-" => Tok::Minus(..),
"+" => Tok::Plus(..),
"*" => Tok::Times(..),
"/" => Tok::Div(..),
"Num" => Tok::Num(<i32>)
}
}
pub Expr: &'ast Node<'ast> = {
<l:Expr> "-" <r:Factor> => arena.alloc(Node::Binary(Op::Sub, l, r));
<l:Expr> "+" <r:Factor> => arena.alloc(Node::Binary(Op::Add, l, r));
Factor;
};
Factor = {
<l:Factor> "*" <r:Term> => arena.alloc(Node::Binary(Op::Mul, l, r));
<l:Factor> "/" <r:Term> => arena.alloc(Node::Binary(Op::Div, l, r));
Term;
};
Term = {
<n:"Num"> => arena.alloc(Node::Value(n));
"(" <Expr> ")";
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
use std::cell::RefCell;
#[derive(Debug, PartialEq, Eq)]
pub enum Op {
Add, Sub, Mul, Div
}
#[derive(Debug, PartialEq, Eq)]
pub enum Node<'ast> {
Value(i32),
Binary(Op, &'ast Node<'ast>, &'ast Node<'ast>),
}
pub struct Arena<'ast> {
data: RefCell<Vec<Box<Node<'ast>>>>
}
impl<'ast> Arena<'ast> {
pub fn new() -> Arena<'ast> {
Arena { data: RefCell::new(vec![]) }
}
pub fn alloc(&'ast self, n: Node<'ast>) -> &'ast Node<'ast> {
let b = Box::new(n);
let p: *const Node<'ast> = &*b;
self.data.borrow_mut().push(b);
unsafe { &*p }
}
}

View File

@ -1,31 +1,36 @@
mod expr; mod expr;
mod expr_arena;
mod expr_arena_ast;
mod sub; mod sub;
mod util; mod util;
use expr::parse_Expr;
fn main() { fn main() {
println!("Hello, world!"); println!("Hello, world!");
} }
#[test] #[test]
fn expr_test1() { fn expr_test1() {
util::test(parse_Expr, "22 - 3", 22 - 3); util::test(|v| expr::parse_Expr(1, v), "22 - 3", 22 - 3);
} }
#[test] #[test]
fn expr_test2() { fn expr_test2() {
util::test(parse_Expr, "22 - (3 + 5)", 22 - (3 + 5)); util::test(|v| expr::parse_Expr(1, v), "22 - (3 + 5)", 22 - (3 + 5));
} }
#[test] #[test]
fn expr_test3() { fn expr_test3() {
util::test(parse_Expr, "22 - (3 - 5) - 13", 22 - (3 - 5) - 13); util::test(|v| expr::parse_Expr(1, v), "22 - (3 - 5) - 13", 22 - (3 - 5) - 13);
} }
#[test] #[test]
fn expr_test4() { fn expr_test4() {
util::test(parse_Expr, "22 * 3 - 6", 22 * 3 - 6); util::test(|v| expr::parse_Expr(1, v), "22 * 3 - 6", 22 * 3 - 6);
}
#[test]
fn expr_test5() {
util::test(|v| expr::parse_Expr(11, v), "22 * 3 - 6", 22*11 * 3*11 - 6*11);
} }
#[test] #[test]
@ -42,3 +47,17 @@ fn sub_test2() {
fn sub_test3() { fn sub_test3() {
util::test(sub::parse_S, "22 - (3 - 5) - 13", 22 - (3 - 5) - 13); util::test(sub::parse_S, "22 - (3 - 5) - 13", 22 - (3 - 5) - 13);
} }
#[test]
fn expr_arena_test1() {
use expr_arena_ast::*;
let mut arena = Arena::new();
let expected =
arena.alloc(Node::Binary(Op::Sub,
arena.alloc(Node::Binary(Op::Mul,
arena.alloc(Node::Value(22)),
arena.alloc(Node::Value(3)))),
arena.alloc(Node::Value(6))));
util::test(|v| expr_arena::parse_Expr(&arena, v), "22 * 3 - 6", expected);
}

View File

@ -20,11 +20,11 @@ mod __parse__S {
use util::tok::Tok; use util::tok::Tok;
pub enum __Nonterminal { pub enum __Nonterminal<> {
T(i32), S(i32),
__S(i32), __S(i32),
E(i32), E(i32),
S(i32), T(i32),
} }
// State 0 // State 0
@ -42,16 +42,17 @@ mod __parse__S {
// "(" -> Shift(S1) // "(" -> Shift(S1)
// "Num" -> Shift(S4) // "Num" -> Shift(S4)
// //
// S -> S2
// E -> S3
// T -> S5 // T -> S5
// E -> S2
// S -> S3
pub fn __state0< pub fn __state0<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(__tok @ Tok::LParen(..)) => { Some(__tok @ Tok::LParen(..)) => {
let mut __sym0 = &mut Some(__tok); let mut __sym0 = &mut Some(__tok);
@ -70,18 +71,18 @@ mod __parse__S {
loop { loop {
let (__lookahead, __nt) = __result; let (__lookahead, __nt) = __result;
match __nt { match __nt {
__Nonterminal::S(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state2(__lookahead, __tokens, __sym0));
}
__Nonterminal::E(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state3(__lookahead, __tokens, __sym0));
}
__Nonterminal::T(__nt) => { __Nonterminal::T(__nt) => {
let __sym0 = &mut Some(__nt); let __sym0 = &mut Some(__nt);
__result = try!(__state5(__lookahead, __tokens, __sym0)); __result = try!(__state5(__lookahead, __tokens, __sym0));
} }
__Nonterminal::E(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state2(__lookahead, __tokens, __sym0));
}
__Nonterminal::S(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state3(__lookahead, __tokens, __sym0));
}
_ => { _ => {
return Ok((__lookahead, __nt)); return Ok((__lookahead, __nt));
} }
@ -101,30 +102,31 @@ mod __parse__S {
// T = (*) "Num" [")"] // T = (*) "Num" [")"]
// T = (*) "Num" ["-"] // T = (*) "Num" ["-"]
// //
// "(" -> Shift(S7)
// "Num" -> Shift(S6) // "Num" -> Shift(S6)
// "(" -> Shift(S9)
// //
// T -> S9
// E -> S8 // E -> S8
// T -> S7
pub fn __state1< pub fn __state1<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>, __sym0: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __sym1 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state7(__lookahead, __tokens, __sym1));
}
Some(Tok::Num(__tok0)) => { Some(Tok::Num(__tok0)) => {
let mut __sym1 = &mut Some((__tok0)); let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next(); let __lookahead = __tokens.next();
__result = try!(__state6(__lookahead, __tokens, __sym1)); __result = try!(__state6(__lookahead, __tokens, __sym1));
} }
Some(__tok @ Tok::LParen(..)) => {
let mut __sym1 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state9(__lookahead, __tokens, __sym1));
}
_ => { _ => {
return Err(__lookahead); return Err(__lookahead);
} }
@ -132,14 +134,14 @@ mod __parse__S {
while __sym0.is_some() { while __sym0.is_some() {
let (__lookahead, __nt) = __result; let (__lookahead, __nt) = __result;
match __nt { match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state9(__lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => { __Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt); let __sym1 = &mut Some(__nt);
__result = try!(__state8(__lookahead, __tokens, __sym0, __sym1)); __result = try!(__state8(__lookahead, __tokens, __sym0, __sym1));
} }
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state7(__lookahead, __tokens, __sym1));
}
_ => { _ => {
return Ok((__lookahead, __nt)); return Ok((__lookahead, __nt));
} }
@ -149,31 +151,6 @@ mod __parse__S {
} }
// State 2 // State 2
// __S = S (*) [EOF]
//
// EOF -> Reduce(__S = S => ActionFn(0);)
//
pub fn __state2<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> {
let mut __result: (Option<Tok>, __Nonterminal);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action0(__sym0);
return Ok((__lookahead, __Nonterminal::__S(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 3
// E = E (*) "-" T [EOF] // E = E (*) "-" T [EOF]
// E = E (*) "-" T ["-"] // E = E (*) "-" T ["-"]
// S = E (*) [EOF] // S = E (*) [EOF]
@ -181,14 +158,15 @@ mod __parse__S {
// "-" -> Shift(S10) // "-" -> Shift(S10)
// EOF -> Reduce(S = E => ActionFn(1);) // EOF -> Reduce(S = E => ActionFn(1);)
// //
pub fn __state3< pub fn __state2<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<i32>, __sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(__tok @ Tok::Minus(..)) => { Some(__tok @ Tok::Minus(..)) => {
let mut __sym1 = &mut Some(__tok); let mut __sym1 = &mut Some(__tok);
@ -197,7 +175,7 @@ mod __parse__S {
} }
None => { None => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __nt = super::__action1(__sym0); let __nt = super::__actions::__action1(__sym0);
return Ok((__lookahead, __Nonterminal::S(__nt))); return Ok((__lookahead, __Nonterminal::S(__nt)));
} }
_ => { _ => {
@ -207,6 +185,32 @@ mod __parse__S {
return Ok(__result); return Ok(__result);
} }
// State 3
// __S = S (*) [EOF]
//
// EOF -> Reduce(__S = S => ActionFn(0);)
//
pub fn __state3<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action0(__sym0);
return Ok((__lookahead, __Nonterminal::__S(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 4 // State 4
// T = "Num" (*) [EOF] // T = "Num" (*) [EOF]
// T = "Num" (*) ["-"] // T = "Num" (*) ["-"]
@ -220,17 +224,18 @@ mod __parse__S {
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<i32>, __sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(Tok::Minus(..)) => { Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __nt = super::__action4(__sym0); let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt))); return Ok((__lookahead, __Nonterminal::T(__nt)));
} }
None => { None => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __nt = super::__action4(__sym0); let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt))); return Ok((__lookahead, __Nonterminal::T(__nt)));
} }
_ => { _ => {
@ -243,8 +248,8 @@ mod __parse__S {
// E = T (*) [EOF] // E = T (*) [EOF]
// E = T (*) ["-"] // E = T (*) ["-"]
// //
// EOF -> Reduce(E = T => ActionFn(3);)
// "-" -> Reduce(E = T => ActionFn(3);) // "-" -> Reduce(E = T => ActionFn(3);)
// EOF -> Reduce(E = T => ActionFn(3);)
// //
pub fn __state5< pub fn __state5<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
@ -252,17 +257,18 @@ mod __parse__S {
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<i32>, __sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => { Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __nt = super::__action3(__sym0); let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt))); return Ok((__lookahead, __Nonterminal::E(__nt)));
} }
_ => { _ => {
@ -275,8 +281,8 @@ mod __parse__S {
// T = "Num" (*) [")"] // T = "Num" (*) [")"]
// T = "Num" (*) ["-"] // T = "Num" (*) ["-"]
// //
// ")" -> Reduce(T = "Num" => ActionFn(4);)
// "-" -> Reduce(T = "Num" => ActionFn(4);) // "-" -> Reduce(T = "Num" => ActionFn(4);)
// ")" -> Reduce(T = "Num" => ActionFn(4);)
// //
pub fn __state6< pub fn __state6<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
@ -284,17 +290,18 @@ mod __parse__S {
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<i32>, __sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => { Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __nt = super::__action4(__sym0); let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt))); return Ok((__lookahead, __Nonterminal::T(__nt)));
} }
_ => { _ => {
@ -304,6 +311,76 @@ mod __parse__S {
} }
// State 7 // State 7
// E = T (*) [")"]
// E = T (*) ["-"]
//
// ")" -> Reduce(E = T => ActionFn(3);)
// "-" -> Reduce(E = T => ActionFn(3);)
//
pub fn __state7<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 8
// E = E (*) "-" T [")"]
// E = E (*) "-" T ["-"]
// T = "(" E (*) ")" [EOF]
// T = "(" E (*) ")" ["-"]
//
// ")" -> Shift(S11)
// "-" -> Shift(S12)
//
pub fn __state8<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::RParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state11(__lookahead, __tokens, __sym0, __sym1, __sym2));
}
Some(__tok @ Tok::Minus(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state12(__lookahead, __tokens, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 9
// E = (*) E "-" T [")"] // E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"] // E = (*) E "-" T ["-"]
// E = (*) T [")"] // E = (*) T [")"]
@ -315,24 +392,25 @@ mod __parse__S {
// T = (*) "Num" [")"] // T = (*) "Num" [")"]
// T = (*) "Num" ["-"] // T = (*) "Num" ["-"]
// //
// "(" -> Shift(S7) // "(" -> Shift(S9)
// "Num" -> Shift(S6) // "Num" -> Shift(S6)
// //
// E -> S11 // T -> S7
// T -> S9 // E -> S13
pub fn __state7< pub fn __state9<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>, __sym0: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(__tok @ Tok::LParen(..)) => { Some(__tok @ Tok::LParen(..)) => {
let mut __sym1 = &mut Some(__tok); let mut __sym1 = &mut Some(__tok);
let __lookahead = __tokens.next(); let __lookahead = __tokens.next();
__result = try!(__state7(__lookahead, __tokens, __sym1)); __result = try!(__state9(__lookahead, __tokens, __sym1));
} }
Some(Tok::Num(__tok0)) => { Some(Tok::Num(__tok0)) => {
let mut __sym1 = &mut Some((__tok0)); let mut __sym1 = &mut Some((__tok0));
@ -346,13 +424,13 @@ mod __parse__S {
while __sym0.is_some() { while __sym0.is_some() {
let (__lookahead, __nt) = __result; let (__lookahead, __nt) = __result;
match __nt { match __nt {
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state11(__lookahead, __tokens, __sym0, __sym1));
}
__Nonterminal::T(__nt) => { __Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt); let __sym1 = &mut Some(__nt);
__result = try!(__state9(__lookahead, __tokens, __sym1)); __result = try!(__state7(__lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state13(__lookahead, __tokens, __sym0, __sym1));
} }
_ => { _ => {
return Ok((__lookahead, __nt)); return Ok((__lookahead, __nt));
@ -362,74 +440,6 @@ mod __parse__S {
return Ok(__result); return Ok(__result);
} }
// State 8
// E = E (*) "-" T [")"]
// E = E (*) "-" T ["-"]
// T = "(" E (*) ")" [EOF]
// T = "(" E (*) ")" ["-"]
//
// "-" -> Shift(S13)
// ")" -> Shift(S12)
//
pub fn __state8<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> {
let mut __result: (Option<Tok>, __Nonterminal);
match __lookahead {
Some(__tok @ Tok::Minus(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state13(__lookahead, __tokens, __sym1, __sym2));
}
Some(__tok @ Tok::RParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state12(__lookahead, __tokens, __sym0, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 9
// E = T (*) [")"]
// E = T (*) ["-"]
//
// ")" -> Reduce(E = T => ActionFn(3);)
// "-" -> Reduce(E = T => ActionFn(3);)
//
pub fn __state9<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> {
let mut __result: (Option<Tok>, __Nonterminal);
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 10 // State 10
// E = E "-" (*) T [EOF] // E = E "-" (*) T [EOF]
// E = E "-" (*) T ["-"] // E = E "-" (*) T ["-"]
@ -438,8 +448,8 @@ mod __parse__S {
// T = (*) "Num" [EOF] // T = (*) "Num" [EOF]
// T = (*) "Num" ["-"] // T = (*) "Num" ["-"]
// //
// "(" -> Shift(S1)
// "Num" -> Shift(S4) // "Num" -> Shift(S4)
// "(" -> Shift(S1)
// //
// T -> S14 // T -> S14
pub fn __state10< pub fn __state10<
@ -449,19 +459,20 @@ mod __parse__S {
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<i32>, __sym0: &mut Option<i32>,
__sym1: &mut Option<Tok>, __sym1: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state1(__lookahead, __tokens, __sym2));
}
Some(Tok::Num(__tok0)) => { Some(Tok::Num(__tok0)) => {
let mut __sym2 = &mut Some((__tok0)); let mut __sym2 = &mut Some((__tok0));
let __lookahead = __tokens.next(); let __lookahead = __tokens.next();
__result = try!(__state4(__lookahead, __tokens, __sym2)); __result = try!(__state4(__lookahead, __tokens, __sym2));
} }
Some(__tok @ Tok::LParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state1(__lookahead, __tokens, __sym2));
}
_ => { _ => {
return Err(__lookahead); return Err(__lookahead);
} }
@ -482,71 +493,36 @@ mod __parse__S {
} }
// State 11 // State 11
// E = E (*) "-" T [")"] // T = "(" E ")" (*) [EOF]
// E = E (*) "-" T ["-"] // T = "(" E ")" (*) ["-"]
// T = "(" E (*) ")" [")"]
// T = "(" E (*) ")" ["-"]
// //
// "-" -> Shift(S13) // "-" -> Reduce(T = "(", E, ")" => ActionFn(5);)
// ")" -> Shift(S15) // EOF -> Reduce(T = "(", E, ")" => ActionFn(5);)
// //
pub fn __state11< pub fn __state11<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> {
let mut __result: (Option<Tok>, __Nonterminal);
match __lookahead {
Some(__tok @ Tok::Minus(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state13(__lookahead, __tokens, __sym1, __sym2));
}
Some(__tok @ Tok::RParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state15(__lookahead, __tokens, __sym0, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 12
// T = "(" E ")" (*) [EOF]
// T = "(" E ")" (*) ["-"]
//
// "-" -> Reduce(T = "(", E, ")" => ActionFn(5);)
// EOF -> Reduce(T = "(", E, ")" => ActionFn(5);)
//
pub fn __state12<
__TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>, __sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>, __sym1: &mut Option<i32>,
__sym2: &mut Option<Tok>, __sym2: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(Tok::Minus(..)) => { Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap(); let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap(); let __sym2 = __sym2.take().unwrap();
let __nt = super::__action5(__sym0, __sym1, __sym2); let __nt = super::__actions::__action5(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::T(__nt))); return Ok((__lookahead, __Nonterminal::T(__nt)));
} }
None => { None => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap(); let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap(); let __sym2 = __sym2.take().unwrap();
let __nt = super::__action5(__sym0, __sym1, __sym2); let __nt = super::__actions::__action5(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::T(__nt))); return Ok((__lookahead, __Nonterminal::T(__nt)));
} }
_ => { _ => {
@ -555,7 +531,7 @@ mod __parse__S {
} }
} }
// State 13 // State 12
// E = E "-" (*) T [")"] // E = E "-" (*) T [")"]
// E = E "-" (*) T ["-"] // E = E "-" (*) T ["-"]
// T = (*) "(" E ")" [")"] // T = (*) "(" E ")" [")"]
@ -563,30 +539,31 @@ mod __parse__S {
// T = (*) "Num" [")"] // T = (*) "Num" [")"]
// T = (*) "Num" ["-"] // T = (*) "Num" ["-"]
// //
// "(" -> Shift(S7)
// "Num" -> Shift(S6) // "Num" -> Shift(S6)
// "(" -> Shift(S9)
// //
// T -> S16 // T -> S15
pub fn __state13< pub fn __state12<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<i32>, __sym0: &mut Option<i32>,
__sym1: &mut Option<Tok>, __sym1: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state7(__lookahead, __tokens, __sym2));
}
Some(Tok::Num(__tok0)) => { Some(Tok::Num(__tok0)) => {
let mut __sym2 = &mut Some((__tok0)); let mut __sym2 = &mut Some((__tok0));
let __lookahead = __tokens.next(); let __lookahead = __tokens.next();
__result = try!(__state6(__lookahead, __tokens, __sym2)); __result = try!(__state6(__lookahead, __tokens, __sym2));
} }
Some(__tok @ Tok::LParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state9(__lookahead, __tokens, __sym2));
}
_ => { _ => {
return Err(__lookahead); return Err(__lookahead);
} }
@ -596,7 +573,7 @@ mod __parse__S {
match __nt { match __nt {
__Nonterminal::T(__nt) => { __Nonterminal::T(__nt) => {
let __sym2 = &mut Some(__nt); let __sym2 = &mut Some(__nt);
__result = try!(__state16(__lookahead, __tokens, __sym0, __sym1, __sym2)); __result = try!(__state15(__lookahead, __tokens, __sym0, __sym1, __sym2));
} }
_ => { _ => {
return Ok((__lookahead, __nt)); return Ok((__lookahead, __nt));
@ -606,6 +583,43 @@ mod __parse__S {
return Ok(__result); return Ok(__result);
} }
// State 13
// E = E (*) "-" T [")"]
// E = E (*) "-" T ["-"]
// T = "(" E (*) ")" [")"]
// T = "(" E (*) ")" ["-"]
//
// ")" -> Shift(S16)
// "-" -> Shift(S12)
//
pub fn __state13<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::RParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state16(__lookahead, __tokens, __sym0, __sym1, __sym2));
}
Some(__tok @ Tok::Minus(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state12(__lookahead, __tokens, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 14 // State 14
// E = E "-" T (*) [EOF] // E = E "-" T (*) [EOF]
// E = E "-" T (*) ["-"] // E = E "-" T (*) ["-"]
@ -621,21 +635,22 @@ mod __parse__S {
__sym0: &mut Option<i32>, __sym0: &mut Option<i32>,
__sym1: &mut Option<Tok>, __sym1: &mut Option<Tok>,
__sym2: &mut Option<i32>, __sym2: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
None => { None => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap(); let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap(); let __sym2 = __sym2.take().unwrap();
let __nt = super::__action2(__sym0, __sym1, __sym2); let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt))); return Ok((__lookahead, __Nonterminal::E(__nt)));
} }
Some(Tok::Minus(..)) => { Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap(); let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap(); let __sym2 = __sym2.take().unwrap();
let __nt = super::__action2(__sym0, __sym1, __sym2); let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt))); return Ok((__lookahead, __Nonterminal::E(__nt)));
} }
_ => { _ => {
@ -645,36 +660,37 @@ mod __parse__S {
} }
// State 15 // State 15
// T = "(" E ")" (*) [")"] // E = E "-" T (*) [")"]
// T = "(" E ")" (*) ["-"] // E = E "-" T (*) ["-"]
// //
// "-" -> Reduce(T = "(", E, ")" => ActionFn(5);) // "-" -> Reduce(E = E, "-", T => ActionFn(2);)
// ")" -> Reduce(T = "(", E, ")" => ActionFn(5);) // ")" -> Reduce(E = E, "-", T => ActionFn(2);)
// //
pub fn __state15< pub fn __state15<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>, __sym0: &mut Option<i32>,
__sym1: &mut Option<i32>, __sym1: &mut Option<Tok>,
__sym2: &mut Option<Tok>, __sym2: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(Tok::Minus(..)) => { Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap(); let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap(); let __sym2 = __sym2.take().unwrap();
let __nt = super::__action5(__sym0, __sym1, __sym2); let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::T(__nt))); return Ok((__lookahead, __Nonterminal::E(__nt)));
} }
Some(Tok::RParen(..)) => { Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap(); let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap(); let __sym2 = __sym2.take().unwrap();
let __nt = super::__action5(__sym0, __sym1, __sym2); let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::T(__nt))); return Ok((__lookahead, __Nonterminal::E(__nt)));
} }
_ => { _ => {
return Err(__lookahead); return Err(__lookahead);
@ -683,36 +699,37 @@ mod __parse__S {
} }
// State 16 // State 16
// E = E "-" T (*) [")"] // T = "(" E ")" (*) [")"]
// E = E "-" T (*) ["-"] // T = "(" E ")" (*) ["-"]
// //
// ")" -> Reduce(E = E, "-", T => ActionFn(2);) // "-" -> Reduce(T = "(", E, ")" => ActionFn(5);)
// "-" -> Reduce(E = E, "-", T => ActionFn(2);) // ")" -> Reduce(T = "(", E, ")" => ActionFn(5);)
// //
pub fn __state16< pub fn __state16<
__TOKENS: Iterator<Item=Tok>, __TOKENS: Iterator<Item=Tok>,
>( >(
mut __lookahead: Option<Tok>, mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS, __tokens: &mut __TOKENS,
__sym0: &mut Option<i32>, __sym0: &mut Option<Tok>,
__sym1: &mut Option<Tok>, __sym1: &mut Option<i32>,
__sym2: &mut Option<i32>, __sym2: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal), Option<Tok>> { ) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
let mut __result: (Option<Tok>, __Nonterminal); {
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead { match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => { Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap(); let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap(); let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap(); let __sym2 = __sym2.take().unwrap();
let __nt = super::__action2(__sym0, __sym1, __sym2); let __nt = super::__actions::__action5(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt))); return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action5(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::T(__nt)));
} }
_ => { _ => {
return Err(__lookahead); return Err(__lookahead);
@ -721,54 +738,59 @@ mod __parse__S {
} }
} }
fn __action0< mod __actions {
>( use util::tok::Tok;
__0: i32,
) -> i32
{
(__0)
}
fn __action1<
>(
__0: i32,
) -> i32
{
(__0)
}
fn __action2< pub fn __action0<
>( >(
l: i32, __0: i32,
_: Tok, ) -> i32
r: i32, {
) -> i32 (__0)
{ }
l-r
}
fn __action3< pub fn __action1<
>( >(
__0: i32, __0: i32,
) -> i32 ) -> i32
{ {
(__0) (__0)
} }
fn __action4< pub fn __action2<
>( >(
__0: i32, l: i32,
) -> i32 _: Tok,
{ r: i32,
(__0) ) -> i32
} {
l-r
}
fn __action5< pub fn __action3<
>( >(
_: Tok, __0: i32,
__0: i32, ) -> i32
_: Tok, {
) -> i32 (__0)
{ }
(__0)
pub fn __action4<
>(
__0: i32,
) -> i32
{
(__0)
}
pub fn __action5<
>(
_: Tok,
__0: i32,
_: Tok,
) -> i32
{
(__0)
}
} }

View File

@ -1,54 +1,16 @@
//! Utilities for testing. //! Utilities for testing.
#![crate_type="rlib"]
#![crate_name="util"]
use std::env;
use std::fmt::Debug; use std::fmt::Debug;
use std::fs::File;
use std::io::{self, Read};
use std::process::exit;
use util::tok::Tok; use util::tok::Tok;
// a simple tokenizer // a simple tokenizer
pub mod tok; pub mod tok;
// a generic main fn suitable for being executed from the makefile pub fn test<R:Debug+Eq,F>(parse_fn: F,
pub fn main<R:Debug>(parse_fn: fn(Vec<Tok>) -> Result<(Option<Tok>,R),Option<Tok>>) { input: &str,
let mut args = env::args().skip(1); expected: R)
where F: FnOnce(Vec<Tok>) -> Result<(Option<Tok>,R),Option<Tok>>
// read the input file {
let mut input = String::new();
match args.next() {
Some(input_path) => {
let mut f = File::open(&input_path).unwrap();
f.read_to_string(&mut input).unwrap();
}
None => {
let mut s = io::stdin();
s.read_to_string(&mut input).unwrap();
}
}
// create tokens
let tokens = tok::tokenize(&input);
// parse
let (lookahead, r) = parse_fn(tokens).unwrap();
// expect input to be completely consumed
if lookahead.is_some() {
println!("input not completely consumed");
exit(1);
}
println!("input ok: {:?}", r);
}
pub fn test<R:Debug+Eq>(parse_fn: fn(Vec<Tok>) -> Result<(Option<Tok>,R),Option<Tok>>,
input: &str,
expected: R) {
// create tokens // create tokens
let tokens = tok::tokenize(input); let tokens = tok::tokenize(input);

View File

@ -99,9 +99,20 @@ fn emit_action_code<W:Write>(grammar: &r::Grammar,
rust: &mut RustWrite<W>) rust: &mut RustWrite<W>)
-> io::Result<()> -> io::Result<()>
{ {
rust!(rust, "");
rust!(rust, "mod {}actions {{", grammar.prefix);
// we always thread the parameters through to the action code,
// even if they are not used, and hence we need to disable the
// unused variables lint, which otherwise gets very excited.
if !grammar.parameters.is_empty() {
rust!(rust, "#![allow(unused_variables)]");
}
try!(emit_uses(grammar, rust));
for (i, defn) in grammar.action_fn_defns.iter().enumerate() { for (i, defn) in grammar.action_fn_defns.iter().enumerate() {
rust!(rust, ""); rust!(rust, "");
try!(rust.write_fn_header( try!(rust.write_pub_fn_header(
grammar, grammar,
format!("{}action{}", grammar.prefix, i), format!("{}action{}", grammar.prefix, i),
vec![], vec![],
@ -115,6 +126,7 @@ fn emit_action_code<W:Write>(grammar: &r::Grammar,
rust!(rust, "{}", defn.code); rust!(rust, "{}", defn.code);
rust!(rust, "}}"); rust!(rust, "}}");
} }
rust!(rust, "}}");
Ok(()) Ok(())
} }

View File

@ -60,6 +60,12 @@ pub enum TypeRef {
types: Vec<TypeRef> types: Vec<TypeRef>
}, },
Ref {
lifetime: Option<InternedString>,
mutable: bool,
referent: Box<TypeRef>,
},
// 'x ==> only should appear within nominal types, but what do we care // 'x ==> only should appear within nominal types, but what do we care
Lifetime(InternedString), Lifetime(InternedString),
@ -349,6 +355,14 @@ impl Display for TypeRef {
write!(fmt, "{}", s), write!(fmt, "{}", s),
TypeRef::OfSymbol(ref s) => TypeRef::OfSymbol(ref s) =>
write!(fmt, "`{}`", s), write!(fmt, "`{}`", s),
TypeRef::Ref { lifetime: None, mutable: false, ref referent } =>
write!(fmt, "&{}", referent),
TypeRef::Ref { lifetime: Some(l), mutable: false, ref referent } =>
write!(fmt, "&{} {}", l, referent),
TypeRef::Ref { lifetime: None, mutable: true, ref referent } =>
write!(fmt, "&mut {}", referent),
TypeRef::Ref { lifetime: Some(l), mutable: true, ref referent } =>
write!(fmt, "&{} mut {}", l, referent),
} }
} }
} }
@ -374,7 +388,11 @@ impl TypeRef {
types: vec![] types: vec![]
}), }),
TypeRef::OfSymbol(_) => TypeRef::OfSymbol(_) =>
unreachable!("OfSymbol produced by parser") unreachable!("OfSymbol produced by parser"),
TypeRef::Ref { lifetime, mutable, ref referent } =>
TypeRepr::Ref { lifetime: lifetime,
mutable: mutable,
referent: Box::new(referent.type_repr()) },
} }
} }
} }

View File

@ -83,6 +83,11 @@ pub enum TypeRepr {
Tuple(Vec<TypeRepr>), Tuple(Vec<TypeRepr>),
Nominal(NominalTypeRepr), Nominal(NominalTypeRepr),
Lifetime(InternedString), Lifetime(InternedString),
Ref {
lifetime: Option<InternedString>,
mutable: bool,
referent: Box<TypeRepr>,
},
} }
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
@ -147,6 +152,14 @@ impl Display for TypeRepr {
write!(fmt, "{}", data), write!(fmt, "{}", data),
TypeRepr::Lifetime(id) => TypeRepr::Lifetime(id) =>
write!(fmt, "{}", id), write!(fmt, "{}", id),
TypeRepr::Ref { lifetime: None, mutable: false, ref referent } =>
write!(fmt, "&{}", referent),
TypeRepr::Ref { lifetime: Some(l), mutable: false, ref referent } =>
write!(fmt, "&{} {}", l, referent),
TypeRepr::Ref { lifetime: None, mutable: true, ref referent } =>
write!(fmt, "&mut {}", referent),
TypeRepr::Ref { lifetime: Some(l), mutable: true, ref referent } =>
write!(fmt, "&{} mut {}", l, referent),
} }
} }
} }
@ -269,5 +282,25 @@ impl Grammar {
None => &[], // this...probably shouldn't happen actually? None => &[], // this...probably shouldn't happen actually?
} }
} }
pub fn user_parameter_refs(&self) -> String {
let mut result = String::new();
for parameter in &self.parameters {
result.push_str(&format!("{}, ", parameter.name));
}
result
}
pub fn user_type_parameter_decls(&self) -> String {
let mut result = String::new();
for parameter in &self.type_parameters {
result.push_str(&format!("{}, ", parameter));
}
result
}
pub fn user_type_parameter_refs(&self) -> String {
self.user_type_parameter_decls()
}
} }

View File

@ -87,7 +87,9 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
} }
fn write_return_type_defn(&mut self) -> io::Result<()> { fn write_return_type_defn(&mut self) -> io::Result<()> {
rust!(self.out, "pub enum {}Nonterminal {{", self.prefix); rust!(self.out, "pub enum {}Nonterminal<{}> {{",
self.prefix,
self.grammar.user_type_parameter_decls());
// make an enum with one variant per nonterminal; I considered // make an enum with one variant per nonterminal; I considered
// making different enums per state, but this would mean we // making different enums per state, but this would mean we
@ -115,8 +117,9 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
rust!(self.out, "{{"); rust!(self.out, "{{");
rust!(self.out, "let mut {}tokens = {}tokens.into_iter();", self.prefix, self.prefix); rust!(self.out, "let mut {}tokens = {}tokens.into_iter();", self.prefix, self.prefix);
rust!(self.out, "let {}lookahead = {}tokens.next();", self.prefix, self.prefix); rust!(self.out, "let {}lookahead = {}tokens.next();", self.prefix, self.prefix);
rust!(self.out, "match try!({}parse{}::{}state0({}lookahead, &mut {}tokens)) {{", rust!(self.out, "match try!({}parse{}::{}state0({}{}lookahead, &mut {}tokens)) {{",
self.prefix, self.start_symbol, self.prefix, self.prefix, self.prefix); self.prefix, self.start_symbol, self.prefix,
self.grammar.user_parameter_refs(), self.prefix, self.prefix);
rust!(self.out, "({}lookahead, {}parse{}::{}Nonterminal::{}({}nt)) => \ rust!(self.out, "({}lookahead, {}parse{}::{}Nonterminal::{}({}nt)) => \
Ok(({}lookahead, {}nt)),", Ok(({}lookahead, {}nt)),",
self.prefix, self.prefix, self.start_symbol, self.prefix, self.start_symbol, self.prefix, self.prefix, self.start_symbol, self.prefix, self.start_symbol,
@ -164,13 +167,15 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
format!("{}state{}", self.prefix, this_index.0), format!("{}state{}", self.prefix, this_index.0),
vec![format!("{}TOKENS: Iterator<Item={}>", self.prefix, terminal_type)], vec![format!("{}TOKENS: Iterator<Item={}>", self.prefix, terminal_type)],
base_args.into_iter().chain(sym_args).collect(), base_args.into_iter().chain(sym_args).collect(),
format!("Result<(Option<{}>, {}Nonterminal), Option<{}>>", format!("Result<(Option<{}>, {}Nonterminal<{}>), Option<{}>>",
terminal_type, self.prefix, terminal_type), terminal_type, self.prefix,
self.grammar.user_type_parameter_refs(),
terminal_type),
vec![])); vec![]));
rust!(self.out, "{{"); rust!(self.out, "{{");
rust!(self.out, "let mut {}result: (Option<{}>, {}Nonterminal);", rust!(self.out, "let mut {}result: (Option<{}>, {}Nonterminal<{}>);",
self.prefix, terminal_type, self.prefix); self.prefix, terminal_type, self.prefix, self.grammar.user_type_parameter_refs());
rust!(self.out, "match {}lookahead {{", self.prefix); rust!(self.out, "match {}lookahead {{", self.prefix);
@ -224,10 +229,12 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
} }
// invoke the action code // invoke the action code
rust!(self.out, "let {}nt = super::{}action{}({});", rust!(self.out, "let {}nt = super::{}actions::{}action{}({}{});",
self.prefix,
self.prefix, self.prefix,
self.prefix, self.prefix,
production.action_fn.index(), production.action_fn.index(),
self.grammar.user_parameter_refs(),
Sep(", ", &transfer_syms)); Sep(", ", &transfer_syms));
// wrap up the result along with the (unused) lookahead // wrap up the result along with the (unused) lookahead
@ -320,8 +327,9 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
let transfer_syms = self.pop_syms(n, m); let transfer_syms = self.pop_syms(n, m);
// invoke next state, transferring the top `m` tokens // invoke next state, transferring the top `m` tokens
format!("try!({}state{}({}{}, {}{}, {}))", format!("try!({}state{}({}{}{}, {}{}, {}))",
self.prefix, next_index.0, self.prefix, next_index.0,
self.grammar.user_parameter_refs(),
self.prefix, lookahead, self.prefix, lookahead,
self.prefix, tokens, self.prefix, tokens,
Sep(", ", &transfer_syms)) Sep(", ", &transfer_syms))

View File

@ -205,6 +205,10 @@ impl MacroExpander {
TypeRef::Lifetime(id), TypeRef::Lifetime(id),
TypeRef::OfSymbol(ref sym) => TypeRef::OfSymbol(ref sym) =>
TypeRef::OfSymbol(sym.clone()), TypeRef::OfSymbol(sym.clone()),
TypeRef::Ref { lifetime, mutable, ref referent } =>
TypeRef::Ref { lifetime: lifetime,
mutable: mutable,
referent: Box::new(self.macro_expand_type_ref(args, referent)) },
TypeRef::Id(id) => { TypeRef::Id(id) => {
match args.get(&NonterminalString(id)) { match args.get(&NonterminalString(id)) {
Some(sym) => TypeRef::OfSymbol(sym.clone()), Some(sym) => TypeRef::OfSymbol(sym.clone()),

View File

@ -202,6 +202,11 @@ impl<'grammar> TypeInferencer<'grammar> {
Ok(TypeRepr::Nominal(NominalTypeRepr { path: vec![id], Ok(TypeRepr::Nominal(NominalTypeRepr { path: vec![id],
types: vec![] })) types: vec![] }))
} }
TypeRef::Ref { lifetime, mutable, ref referent } => {
Ok(TypeRepr::Ref { lifetime: lifetime,
mutable: mutable,
referent: Box::new(try!(self.type_ref(referent))) })
}
TypeRef::OfSymbol(ref symbol) => { TypeRef::OfSymbol(ref symbol) => {
self.symbol_type(symbol) self.symbol_type(symbol)
} }

View File

@ -189,7 +189,8 @@ rusty_peg! {
// TypeRef // TypeRef
TYPE_REF: TypeRef = TYPE_REF: TypeRef =
(TUPLE_TYPE_REF / LIFETIME_TYPE_REF / NOMINAL_TYPE_REF / ESCAPE_TYPE_REF); (TUPLE_TYPE_REF / LIFETIME_TYPE_REF / NOMINAL_TYPE_REF /
REF_TYPE_REF / REF_MUT_TYPE_REF / ESCAPE_TYPE_REF);
TUPLE_TYPE_REF: TypeRef = TUPLE_TYPE_REF: TypeRef =
("(" <l:TYPE_REF_LIST> ")") => TypeRef::Tuple(l); ("(" <l:TYPE_REF_LIST> ")") => TypeRef::Tuple(l);
@ -200,6 +201,16 @@ rusty_peg! {
ESCAPE_TYPE_REF: TypeRef = ESCAPE_TYPE_REF: TypeRef =
("`" <s:SYMBOL> "`") => TypeRef::OfSymbol(s.kind); ("`" <s:SYMBOL> "`") => TypeRef::OfSymbol(s.kind);
REF_TYPE_REF: TypeRef =
("&" <l:[LIFETIME]> <t:TYPE_REF>) => TypeRef::Ref { lifetime: l,
mutable: false,
referent: Box::new(t) };
REF_MUT_TYPE_REF: TypeRef =
("&" <l:[LIFETIME]> "mut" <t:TYPE_REF>) => TypeRef::Ref { lifetime: l,
mutable: true,
referent: Box::new(t) };
NOMINAL_TYPE_REF: TypeRef = NOMINAL_TYPE_REF: TypeRef =
(<p:PATH> <a:[NOMINAL_TYPE_REF_ARGS]>) => { (<p:PATH> <a:[NOMINAL_TYPE_REF_ARGS]>) => {
if p.len() == 1 && a.is_none() { if p.len() == 1 && a.is_none() {
@ -340,7 +351,8 @@ rusty_peg! {
ID_RE: &'input str = ID_RE: &'input str =
regex(r"[a-zA-Z_][a-zA-Z0-9_]*") - [ regex(r"[a-zA-Z_][a-zA-Z0-9_]*") - [
"if", "use", "where", "token", "grammar", "pub", "struct", "extern", "enum" "if", "use", "where", "token", "grammar", "pub", "struct", "extern", "enum",
"mut"
]; ];
ESCAPE: InternedString = ESCAPE: InternedString =

View File

@ -86,19 +86,6 @@ impl<W:Write> RustWrite<W> {
parameters, return_type, where_clauses) parameters, return_type, where_clauses)
} }
pub fn write_fn_header(&mut self,
grammar: &Grammar,
name: String,
type_parameters: Vec<String>,
parameters: Vec<String>,
return_type: String,
where_clauses: Vec<String>)
-> io::Result<()>
{
self.write_fn_header_helper(grammar, "", name, type_parameters,
parameters, return_type, where_clauses)
}
fn write_fn_header_helper(&mut self, fn write_fn_header_helper(&mut self,
grammar: &Grammar, grammar: &Grammar,
qualifiers: &str, qualifiers: &str,