modify generate code to require a utility library (lalrpop-util) and

to generate errors based on the error type defined therein
This commit is contained in:
Niko Matsakis 2015-07-21 05:18:32 -04:00
parent 91dc00aa89
commit 0530810f10
11 changed files with 4984 additions and 4612 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +1,24 @@
#![allow(unused_imports)]
use util::tok::Tok;
extern crate lalrpop_util as __lalrpop_util;
use self::__lalrpop_util::ParseError as __ParseError;
#[allow(non_snake_case)]
pub fn parse_Items<
__TOKENS: IntoIterator<Item=(usize, Tok, usize)>,
>(
__tokens: __TOKENS,
) -> Result<Vec<(usize, usize)>, Option<(usize, Tok, usize)>>
) -> Result<Vec<(usize, usize)>, __ParseError<usize,Tok>>
{
let mut __tokens = __tokens.into_iter();
let __lookahead = __tokens.next();
match __parse__Items::__state0(None, __lookahead, &mut __tokens) {
Err(None) => {
Err(None)
match try!(__parse__Items::__state0(None, __lookahead, &mut __tokens)) {
(_, Some(__lookahead), _) => {
Err(__ParseError::ExtraToken { token: __lookahead })
}
Err(Some(__lookahead)) => {
Err(Some(__lookahead))
}
Ok((_, Some(__lookahead), _)) => {
Err(Some(__lookahead))
}
Ok((_, None, __parse__Items::__Nonterminal::____Items(__nt))) => {
(_, None, __parse__Items::__Nonterminal::____Items(__nt)) => {
Ok(__nt)
}
Ok(_) => unreachable!(),
_ => unreachable!(),
}
}
@ -35,11 +30,11 @@ mod __parse__Items {
use self::__lalrpop_util::ParseError as __ParseError;
pub enum __Nonterminal<> {
_40_3e(usize),
____Items(Vec<(usize, usize)>),
_40_3c(usize),
Spanned_3c_22_2b_22_3e((usize, usize)),
Items(Vec<(usize, usize)>),
_40_3c(usize),
____Items(Vec<(usize, usize)>),
_40_3e(usize),
Spanned_3c_22_2b_22_3e((usize, usize)),
}
// State 0
@ -69,7 +64,7 @@ mod __parse__Items {
__lookbehind: Option<usize>,
__lookahead: Option<(usize, Tok, usize)>,
__tokens: &mut __TOKENS,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
@ -86,7 +81,10 @@ mod __parse__Items {
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3c(__nt));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
loop {
@ -120,12 +118,12 @@ mod __parse__Items {
// Spanned<"+"> = (*) @< "+" @> ["-"]
// __Items = Items (*) [EOF]
//
// EOF -> Reduce(__Items = Items => Call(ActionFn(0));)
// "+" -> Reduce(@< = => Lookahead;)
// "-" -> Shift(S4)
// EOF -> Reduce(__Items = Items => Call(ActionFn(0));)
// "-" -> Shift(S5)
//
// @< -> S4
// Spanned<"+"> -> S3
// @< -> S5
pub fn __state1<
__TOKENS: Iterator<Item=(usize, Tok, usize)>,
>(
@ -133,7 +131,7 @@ mod __parse__Items {
__lookahead: Option<(usize, Tok, usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Vec<(usize, usize)>>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
@ -141,32 +139,35 @@ mod __parse__Items {
let mut __lookbehind = Some(__loc);
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state4(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
__result = try!(__state5(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
Some((_, Tok::Plus(..), _)) => {
let __nt = __lookahead.as_ref().map(|o| ::std::clone::Clone::clone(&o.0)).or_else(|| ::std::clone::Clone::clone(&__lookbehind)).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3c(__nt));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action0(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::____Items(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __nt = __lookahead.as_ref().map(|o| ::std::clone::Clone::clone(&o.0)).or_else(|| ::std::clone::Clone::clone(&__lookbehind)).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3c(__nt));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
while __sym0.is_some() {
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::_40_3c(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state4(__lookbehind, __lookahead, __tokens, __sym1));
}
__Nonterminal::Spanned_3c_22_2b_22_3e(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state3(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
__Nonterminal::_40_3c(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state5(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
}
@ -184,8 +185,8 @@ mod __parse__Items {
// Items = @< (*) @> ["-"]
//
// "+" -> Reduce(@> = => Lookbehind;)
// EOF -> Reduce(@> = => Lookbehind;)
// "-" -> Reduce(@> = => Lookbehind;)
// EOF -> Reduce(@> = => Lookbehind;)
//
// @> -> S6
pub fn __state2<
@ -195,7 +196,7 @@ mod __parse__Items {
__lookahead: Option<(usize, Tok, usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<usize>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
@ -203,16 +204,19 @@ mod __parse__Items {
let __nt = ::std::clone::Clone::clone(&__lookbehind).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
None => {
let __nt = ::std::clone::Clone::clone(&__lookbehind).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
Some((_, Tok::Minus(..), _)) => {
let __nt = ::std::clone::Clone::clone(&__lookbehind).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
None => {
let __nt = ::std::clone::Clone::clone(&__lookbehind).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
while __sym0.is_some() {
@ -235,9 +239,9 @@ mod __parse__Items {
// Items = Items Spanned<"+"> (*) ["+"]
// Items = Items Spanned<"+"> (*) ["-"]
//
// EOF -> Reduce(Items = Items, Spanned<"+"> => Call(ActionFn(2));)
// "+" -> Reduce(Items = Items, Spanned<"+"> => Call(ActionFn(2));)
// "-" -> Reduce(Items = Items, Spanned<"+"> => Call(ActionFn(2));)
// EOF -> Reduce(Items = Items, Spanned<"+"> => Call(ActionFn(2));)
//
pub fn __state3<
__TOKENS: Iterator<Item=(usize, Tok, usize)>,
@ -247,10 +251,16 @@ mod __parse__Items {
__tokens: &mut __TOKENS,
__sym0: &mut Option<Vec<(usize, usize)>>,
__sym1: &mut Option<(usize, usize)>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action2(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
@ -263,78 +273,30 @@ mod __parse__Items {
let __nt = super::__action2(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action2(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
}
// State 4
// Items = Items "-" (*) [EOF]
// Items = Items "-" (*) ["+"]
// Items = Items "-" (*) ["-"]
// Spanned<"+"> = @< (*) "+" @> [EOF]
// Spanned<"+"> = @< (*) "+" @> ["+"]
// Spanned<"+"> = @< (*) "+" @> ["-"]
//
// EOF -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
// "-" -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
// "+" -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
// "+" -> Shift(S7)
//
pub fn __state4<
__TOKENS: Iterator<Item=(usize, Tok, usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize, Tok, usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Vec<(usize, usize)>>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Minus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 5
// Spanned<"+"> = @< (*) "+" @> [EOF]
// Spanned<"+"> = @< (*) "+" @> ["+"]
// Spanned<"+"> = @< (*) "+" @> ["-"]
//
// "+" -> Shift(S7)
//
pub fn __state5<
__TOKENS: Iterator<Item=(usize, Tok, usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize, Tok, usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<usize>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
@ -345,20 +307,71 @@ mod __parse__Items {
__result = try!(__state7(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
return Ok(__result);
}
// State 5
// Items = Items "-" (*) [EOF]
// Items = Items "-" (*) ["+"]
// Items = Items "-" (*) ["-"]
//
// "-" -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
// "+" -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
// EOF -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
//
pub fn __state5<
__TOKENS: Iterator<Item=(usize, Tok, usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize, Tok, usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Vec<(usize, usize)>>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
Some((_, Tok::Minus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
_ => {
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
}
// State 6
// Items = @< @> (*) [EOF]
// Items = @< @> (*) ["+"]
// Items = @< @> (*) ["-"]
//
// "-" -> Reduce(Items = @<, @> => Call(ActionFn(1));)
// EOF -> Reduce(Items = @<, @> => Call(ActionFn(1));)
// "+" -> Reduce(Items = @<, @> => Call(ActionFn(1));)
// "-" -> Reduce(Items = @<, @> => Call(ActionFn(1));)
//
pub fn __state6<
__TOKENS: Iterator<Item=(usize, Tok, usize)>,
@ -368,10 +381,16 @@ mod __parse__Items {
__tokens: &mut __TOKENS,
__sym0: &mut Option<usize>,
__sym1: &mut Option<usize>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
Some((_, Tok::Minus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action1(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
@ -384,14 +403,11 @@ mod __parse__Items {
let __nt = super::__action1(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Minus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__action1(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
}
@ -404,9 +420,9 @@ mod __parse__Items {
// Spanned<"+"> = @< "+" (*) @> ["+"]
// Spanned<"+"> = @< "+" (*) @> ["-"]
//
// EOF -> Reduce(@> = => Lookbehind;)
// "-" -> Reduce(@> = => Lookbehind;)
// "+" -> Reduce(@> = => Lookbehind;)
// "-" -> Reduce(@> = => Lookbehind;)
// EOF -> Reduce(@> = => Lookbehind;)
//
// @> -> S8
pub fn __state7<
@ -417,11 +433,11 @@ mod __parse__Items {
__tokens: &mut __TOKENS,
__sym0: &mut Option<usize>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
None => {
Some((_, Tok::Plus(..), _)) => {
let __nt = ::std::clone::Clone::clone(&__lookbehind).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
@ -429,12 +445,15 @@ mod __parse__Items {
let __nt = ::std::clone::Clone::clone(&__lookbehind).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
Some((_, Tok::Plus(..), _)) => {
None => {
let __nt = ::std::clone::Clone::clone(&__lookbehind).unwrap_or_default();
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
while __sym1.is_some() {
@ -458,8 +477,8 @@ mod __parse__Items {
// Spanned<"+"> = @< "+" @> (*) ["-"]
//
// "-" -> Reduce(Spanned<"+"> = @<, "+", @> => Call(ActionFn(4));)
// EOF -> Reduce(Spanned<"+"> = @<, "+", @> => Call(ActionFn(4));)
// "+" -> Reduce(Spanned<"+"> = @<, "+", @> => Call(ActionFn(4));)
// EOF -> Reduce(Spanned<"+"> = @<, "+", @> => Call(ActionFn(4));)
//
pub fn __state8<
__TOKENS: Iterator<Item=(usize, Tok, usize)>,
@ -470,7 +489,7 @@ mod __parse__Items {
__sym0: &mut Option<usize>,
__sym1: &mut Option<Tok>,
__sym2: &mut Option<usize>,
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), Option<(usize, Tok, usize)>>
) -> Result<(Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>), __ParseError<usize,Tok>>
{
let mut __result: (Option<usize>, Option<(usize, Tok, usize)>, __Nonterminal<>);
match __lookahead {
@ -481,13 +500,6 @@ mod __parse__Items {
let __nt = super::__action4(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::Spanned_3c_22_2b_22_3e(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__action4(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::Spanned_3c_22_2b_22_3e(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
@ -495,8 +507,18 @@ mod __parse__Items {
let __nt = super::__action4(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::Spanned_3c_22_2b_22_3e(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__action4(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::Spanned_3c_22_2b_22_3e(__nt)));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
}

View File

@ -1,3 +1,5 @@
extern crate lalrpop_util;
/// demonstration from the Greene text; one of the simplest grammars
/// that still ensures we get parse tree correct
mod sub;

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +1,25 @@
#![allow(unused_imports)]
use super::util::tok::Tok;
extern crate lalrpop_util as __lalrpop_util;
use self::__lalrpop_util::ParseError as __ParseError;
#[allow(non_snake_case)]
pub fn parse_S<
__TOKENS: IntoIterator<Item=Tok>,
>(
__tokens: __TOKENS,
) -> Result<i32, Option<Tok>>
) -> Result<i32, __ParseError<(),Tok>>
{
let mut __tokens = __tokens.into_iter();
let mut __tokens = __tokens.map(|t| ((), t, ()));
let __lookahead = __tokens.next();
match __parse__S::__state0(None, __lookahead, &mut __tokens) {
Err(None) => {
Err(None)
match try!(__parse__S::__state0(None, __lookahead, &mut __tokens)) {
(_, Some(__lookahead), _) => {
Err(__ParseError::ExtraToken { token: __lookahead })
}
Err(Some(__lookahead)) => {
Err(Some(__lookahead.1))
}
Ok((_, Some(__lookahead), _)) => {
Err(Some(__lookahead.1))
}
Ok((_, None, __parse__S::__Nonterminal::____S(__nt))) => {
(_, None, __parse__S::__Nonterminal::____S(__nt)) => {
Ok(__nt)
}
Ok(_) => unreachable!(),
_ => unreachable!(),
}
}
@ -36,24 +31,24 @@ mod __parse__S {
use self::__lalrpop_util::ParseError as __ParseError;
pub enum __Nonterminal<> {
S(i32),
____S(i32),
S(i32),
}
// State 0
// S = (*) "(" ")" [EOF]
// __S = (*) S [EOF]
//
// "(" -> Shift(S2)
// "(" -> Shift(S1)
//
// S -> S1
// S -> S2
pub fn __state0<
__TOKENS: Iterator<Item=((), Tok, ())>,
>(
__lookbehind: Option<()>,
__lookahead: Option<((), Tok, ())>,
__tokens: &mut __TOKENS,
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), Option<((), Tok, ())>>
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), __ParseError<(),Tok>>
{
let mut __result: (Option<()>, Option<((), Tok, ())>, __Nonterminal<>);
match __lookahead {
@ -61,10 +56,13 @@ mod __parse__S {
let mut __lookbehind = Some(__loc);
let mut __sym0 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state2(__lookbehind, __lookahead, __tokens, __sym0));
__result = try!(__state1(__lookbehind, __lookahead, __tokens, __sym0));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
loop {
@ -72,7 +70,7 @@ mod __parse__S {
match __nt {
__Nonterminal::S(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state1(__lookbehind, __lookahead, __tokens, __sym0));
__result = try!(__state2(__lookbehind, __lookahead, __tokens, __sym0));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
@ -82,45 +80,18 @@ mod __parse__S {
}
// State 1
// __S = S (*) [EOF]
// S = "(" (*) ")" [EOF]
//
// EOF -> Reduce(__S = S => Call(ActionFn(0));)
// ")" -> Shift(S3)
//
pub fn __state1<
__TOKENS: Iterator<Item=((), Tok, ())>,
>(
__lookbehind: Option<()>,
__lookahead: Option<((), Tok, ())>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), Option<((), Tok, ())>>
{
let mut __result: (Option<()>, Option<((), Tok, ())>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action0(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::____S(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 2
// S = "(" (*) ")" [EOF]
//
// ")" -> Shift(S3)
//
pub fn __state2<
__TOKENS: Iterator<Item=((), Tok, ())>,
>(
__lookbehind: Option<()>,
__lookahead: Option<((), Tok, ())>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), Option<((), Tok, ())>>
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), __ParseError<(),Tok>>
{
let mut __result: (Option<()>, Option<((), Tok, ())>, __Nonterminal<>);
match __lookahead {
@ -131,12 +102,45 @@ mod __parse__S {
__result = try!(__state3(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
return Ok(__result);
}
// State 2
// __S = S (*) [EOF]
//
// EOF -> Reduce(__S = S => Call(ActionFn(0));)
//
pub fn __state2<
__TOKENS: Iterator<Item=((), Tok, ())>,
>(
__lookbehind: Option<()>,
__lookahead: Option<((), Tok, ())>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), __ParseError<(),Tok>>
{
let mut __result: (Option<()>, Option<((), Tok, ())>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__action0(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::____S(__nt)));
}
_ => {
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
}
// State 3
// S = "(" ")" (*) [EOF]
//
@ -150,7 +154,7 @@ mod __parse__S {
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), Option<((), Tok, ())>>
) -> Result<(Option<()>, Option<((), Tok, ())>, __Nonterminal<>), __ParseError<(),Tok>>
{
let mut __result: (Option<()>, Option<((), Tok, ())>, __Nonterminal<>);
match __lookahead {
@ -161,7 +165,10 @@ mod __parse__S {
return Ok((__lookbehind, __lookahead, __Nonterminal::S(__nt)));
}
_ => {
return Err(__lookahead);
return Err(__ParseError::UnrecognizedToken {
token: __lookahead,
expected: vec![],
});
}
}
}

View File

@ -2,6 +2,7 @@
use std::fmt::Debug;
use util::tok::Tok;
use lalrpop_util::ParseError;
// a simple tokenizer
pub mod tok;
@ -9,7 +10,7 @@ pub mod tok;
pub fn test<R:Debug+Eq,F>(parse_fn: F,
input: &str,
expected: R)
where F: FnOnce(Vec<Tok>) -> Result<R,Option<Tok>>
where F: FnOnce(Vec<Tok>) -> Result<R,ParseError<(),Tok>>
{
// create tokens
let tokens = tok::tokenize(input);
@ -27,7 +28,7 @@ pub fn test<R:Debug+Eq,F>(parse_fn: F,
pub fn test_loc<R:Debug+Eq,F>(parse_fn: F,
input: &str,
expected: R)
where F: FnOnce(Vec<(usize, Tok, usize)>) -> Result<R, Option<(usize, Tok, usize)>>
where F: FnOnce(Vec<(usize, Tok, usize)>) -> Result<R, ParseError<usize, Tok>>
{
// create tokens
let tokens = tok::tokenize(input);

View File

@ -1,22 +1,50 @@
pub trait Token {
/// The type of a "location" in the source. Often usize,
/// indicating the byte offset within the file, but it might be
/// anything else you like.
type Loc;
use std::error::Error;
/// The type of the "enum" that the parser generator will use for
/// matching.
type Enum;
#[derive(Debug)]
pub enum ParseError<L,T> {
/// Generated by the parser when it encounters a token (or EOF) it did not
/// expect.
UnrecognizedToken {
/// If this is `Some`, then an unexpected token of type `T`
/// was observed, with a span given by the two `L` values. If
/// this is `None`, then EOF was observed when it was not
/// expected.
token: Option<(L, T, L)>,
/// Extract the start location of this token. That is, the
/// position of the first character.
fn to_start_loc(&self) -> Self::Loc;
/// The set of expected tokens: these names are taken from the
/// grammar and hence may not necessarily be suitable for
/// presenting to the user.
expected: Vec<String>
},
/// Extract the end location of this token. That is, the position
/// of the last character (inclusive or exclusive, your call).
fn to_end_loc(&self) -> Self::Loc;
/// Generated by the parser when it encounters additional,
/// unexpected tokens.
ExtraToken {
token: (L, T, L),
},
/// Convert the token into the enum that the parser generator will
/// use for matching.
fn as_enum(&self) -> &Self::Enum;
/// Just a string describing the error. This is easy to generate,
/// but suboptimal as it has no span or anything
/// else. Occasionally useful from action code but generally to be
/// avoided.
Message {
message: String
},
/// A string describing the error and a span in the source. This
/// is This is easy to generate,
/// but suboptimal as it has no span or anything
/// else. Occasionally useful from action code but generally to be
/// avoided.
MessageSpan {
start: (L, L),
message: String,
},
/// A richer alternative to `Message`, error objects offer more
/// information and reflection.
ErrorObject {
error: Box<Error>,
},
}

View File

@ -88,11 +88,7 @@ fn emit_uses<W:Write>(grammar: &r::Grammar,
rust: &mut RustWrite<W>)
-> io::Result<()>
{
for u in &grammar.uses {
rust!(rust, "use {};", u);
}
rust!(rust, "");
Ok(())
rust.write_uses("", grammar)
}
fn emit_recursive_ascent(output_path: &Path, grammar: &r::Grammar) -> io::Result<()>

View File

@ -84,22 +84,7 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
}
fn write_uses(&mut self) -> io::Result<()> {
// things the user wrote
for u in &self.grammar.uses {
if u.starts_with("super::") {
rust!(self.out, "use super::{};", u);
} else {
rust!(self.out, "use {};", u);
}
}
// stuff that we plan to use
rust!(self.out, "extern crate lalrpop_util as {}lalrpop_util;",
self.prefix);
rust!(self.out, "use self::{}lalrpop_util::ParseError as {}ParseError;",
self.prefix, self.prefix);
Ok(())
self.out.write_uses("super::", &self.grammar)
}
fn write_return_type_defn(&mut self) -> io::Result<()> {
@ -124,6 +109,7 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
// consumed.
fn write_start_fn(&mut self) -> io::Result<()> {
let triple_type = self.triple_type();
let error_type = self.error_type();
let user_token_type = match self.types.opt_terminal_loc_type() {
Some(_) => format!("{}", triple_type),
@ -136,8 +122,9 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
format!("parse_{}", self.user_start_symbol),
vec![format!("{}TOKENS: IntoIterator<Item={}>", self.prefix, user_token_type)],
vec![format!("{}tokens: {}TOKENS", self.prefix, self.prefix)],
format!("Result<{}, Option<{}>>",
self.types.nonterminal_type(self.start_symbol), user_token_type),
format!("Result<{}, {}>",
self.types.nonterminal_type(self.start_symbol),
error_type),
vec![]));
rust!(self.out, "{{");
@ -150,39 +137,25 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
}
rust!(self.out, "let {}lookahead = {}tokens.next();", self.prefix, self.prefix);
rust!(self.out, "match {}parse{}::{}state0({}None, {}lookahead, &mut {}tokens) {{",
rust!(self.out, "match try!({}parse{}::{}state0({}None, {}lookahead, &mut {}tokens)) {{",
self.prefix, self.start_symbol, self.prefix,
self.grammar.user_parameter_refs(), self.prefix, self.prefix);
let transformed_lookahead = match self.types.opt_terminal_loc_type() {
Some(_) => format!("{}lookahead", self.prefix),
None => format!("{}lookahead.1", self.prefix),
};
// unexpected EOF?
rust!(self.out, "Err(None) => {{");
rust!(self.out, "Err(None)");
rust!(self.out, "}}");
// unexpected token during parsing?
rust!(self.out, "Err(Some({}lookahead)) => {{", self.prefix);
rust!(self.out, "Err(Some({}))", transformed_lookahead);
rust!(self.out, "}}");
// extra tokens?
rust!(self.out, "Ok((_, Some({}lookahead), _)) => {{", self.prefix);
rust!(self.out, "Err(Some({}))", transformed_lookahead);
rust!(self.out, "(_, Some({}lookahead), _) => {{", self.prefix);
rust!(self.out, "Err({}ParseError::ExtraToken {{ token: {}lookahead }})",
self.prefix, self.prefix);
rust!(self.out, "}}");
// otherwise, we expect to see only the goal terminal
rust!(self.out, "Ok((_, None, {}parse{}::{}Nonterminal::{}({}nt))) => {{",
rust!(self.out, "(_, None, {}parse{}::{}Nonterminal::{}({}nt)) => {{",
self.prefix, self.start_symbol, self.prefix, Escape(self.start_symbol),
self.prefix);
rust!(self.out, "Ok({}nt)", self.prefix);
rust!(self.out, "}}");
// nothing else should be possible
rust!(self.out, "Ok(_) => unreachable!(),");
rust!(self.out, "_ => unreachable!(),");
rust!(self.out, "}}");
rust!(self.out, "}}");
@ -194,6 +167,7 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
let this_prefix = self.state_prefixes[this_index.0];
let loc_type = self.types.terminal_loc_type();
let triple_type = self.triple_type();
let error_type = self.error_type();
// Leave a comment explaining what this state is.
rust!(self.out, "// State {}", this_index.0);
@ -227,11 +201,11 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
format!("{}state{}", self.prefix, this_index.0),
vec![format!("{}TOKENS: Iterator<Item={}>", self.prefix, triple_type)],
base_args.into_iter().chain(sym_args).collect(),
format!("Result<(Option<{}>, Option<{}>, {}Nonterminal<{}>), Option<{}>>",
format!("Result<(Option<{}>, Option<{}>, {}Nonterminal<{}>), {}>",
loc_type,
triple_type, self.prefix,
self.grammar.user_type_parameter_refs(),
triple_type),
error_type),
vec![]));
rust!(self.out, "{{");
@ -344,7 +318,10 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
// if we hit this, the next token is not recognized, so generate an error
rust!(self.out, "_ => {{");
rust!(self.out, "return Err({}lookahead);", self.prefix);
rust!(self.out, "return Err({}ParseError::UnrecognizedToken {{", self.prefix);
rust!(self.out, "token: {}lookahead,", self.prefix);
rust!(self.out, "expected: vec![],");
rust!(self.out, "}});");
rust!(self.out, "}}");
rust!(self.out, "}}"); // match
@ -478,5 +455,12 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
fn triple_type(&mut self) -> TypeRepr {
self.types.triple_type()
}
fn error_type(&mut self) -> String {
format!("{}ParseError<{},{}>",
self.prefix,
self.types.terminal_loc_type(),
self.types.terminal_enum_type())
}
}

View File

@ -130,4 +130,27 @@ impl<W:Write> RustWrite<W> {
Ok(())
}
pub fn write_uses(&mut self,
super_prefix: &str,
grammar: &Grammar)
-> io::Result<()>
{
// things the user wrote
for u in &grammar.uses {
if u.starts_with("super::") {
rust!(self, "use {}{};", super_prefix, u);
} else {
rust!(self, "use {};", u);
}
}
// stuff that we plan to use
rust!(self, "extern crate lalrpop_util as {}lalrpop_util;",
grammar.prefix);
rust!(self, "use self::{}lalrpop_util::ParseError as {}ParseError;",
grammar.prefix, grammar.prefix);
Ok(())
}
}