thread through most of the work to support lookahead/lookbehind,

but not the actual expansion (untested, clearly)
This commit is contained in:
Niko Matsakis 2015-07-18 05:56:42 -04:00
parent fad838a361
commit f758e0ff00
14 changed files with 4245 additions and 3804 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,8 @@ pub fn parse_S<
{
let mut __tokens = __tokens.into_iter();
let __lookahead = __tokens.next();
match try!(__parse__S::__state0(__lookahead, &mut __tokens)) {
(__lookahead, __parse__S::__Nonterminal::____S(__nt)) => Ok((__lookahead, __nt)),
match try!(__parse__S::__state0(None, __lookahead, &mut __tokens)) {
(_, __lookahead, __parse__S::__Nonterminal::____S(__nt)) => Ok((__lookahead, __nt)),
_ => unreachable!(),
}
}
@ -22,10 +22,10 @@ mod __parse__S {
use util::tok::Tok;
pub enum __Nonterminal<> {
S(i32),
____S(i32),
E(i32),
T(i32),
S(i32),
E(i32),
____S(i32),
}
// State 0
@ -40,88 +40,95 @@ mod __parse__S {
// T = (*) "Num" ["-"]
// __S = (*) S [EOF]
//
// "Num" -> Shift(S4)
// "(" -> Shift(S5)
// "(" -> Shift(S4)
// "Num" -> Shift(S5)
//
// E -> S3
// T -> S1
// T -> S3
// S -> S2
// E -> S1
pub fn __state0<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Num(__tok0)) => {
let mut __sym0 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state4(__lookahead, __tokens, __sym0));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym0 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state5(__lookahead, __tokens, __sym0));
__result = try!(__state4(__lookbehind, __lookahead, __tokens, __sym0));
}
Some(Tok::Num(__tok0)) => {
let mut __lookbehind = None;
let mut __sym0 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state5(__lookbehind, __lookahead, __tokens, __sym0));
}
_ => {
return Err(__lookahead);
}
}
loop {
let (__lookahead, __nt) = __result;
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::E(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state3(__lookahead, __tokens, __sym0));
}
__Nonterminal::T(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state1(__lookahead, __tokens, __sym0));
__result = try!(__state3(__lookbehind, __lookahead, __tokens, __sym0));
}
__Nonterminal::S(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state2(__lookahead, __tokens, __sym0));
__result = try!(__state2(__lookbehind, __lookahead, __tokens, __sym0));
}
__Nonterminal::E(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state1(__lookbehind, __lookahead, __tokens, __sym0));
}
_ => {
return Ok((__lookahead, __nt));
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
}
// State 1
// E = T (*) [EOF]
// E = T (*) ["-"]
// E = E (*) "-" T [EOF]
// E = E (*) "-" T ["-"]
// S = E (*) [EOF]
//
// EOF -> Reduce(E = T => Call(ActionFn(3));)
// "-" -> Reduce(E = T => Call(ActionFn(3));)
// EOF -> Reduce(S = E => Call(ActionFn(1));)
// "-" -> Shift(S6)
//
pub fn __state1<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::Minus(..)) => {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state6(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
None => {
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)));
let __nt = super::__actions::__action1(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::S(__nt)));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 2
@ -132,17 +139,18 @@ mod __parse__S {
pub fn __state2<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action0(__sym0);
return Ok((__lookahead, __Nonterminal::____S(__nt)));
return Ok((__lookbehind, __lookahead, __Nonterminal::____S(__nt)));
}
_ => {
return Err(__lookahead);
@ -151,66 +159,32 @@ mod __parse__S {
}
// State 3
// E = E (*) "-" T [EOF]
// E = E (*) "-" T ["-"]
// S = E (*) [EOF]
// E = T (*) [EOF]
// E = T (*) ["-"]
//
// EOF -> Reduce(S = E => Call(ActionFn(1));)
// "-" -> Shift(S6)
// EOF -> Reduce(E = T => Call(ActionFn(3));)
// "-" -> Reduce(E = T => Call(ActionFn(3));)
//
pub fn __state3<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::Minus(..)) => {
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state6(__lookahead, __tokens, __sym0, __sym1));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action1(__sym0);
return Ok((__lookahead, __Nonterminal::S(__nt)));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 4
// T = "Num" (*) [EOF]
// T = "Num" (*) ["-"]
//
// EOF -> Reduce(T = "Num" => Call(ActionFn(4));)
// "-" -> Reduce(T = "Num" => Call(ActionFn(4));)
//
pub fn __state4<
__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<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
@ -218,7 +192,7 @@ mod __parse__S {
}
}
// State 5
// State 4
// E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"]
// E = (*) T [")"]
@ -230,54 +204,91 @@ mod __parse__S {
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "(" -> Shift(S8)
// "Num" -> Shift(S10)
// "(" -> Shift(S8)
//
// T -> S9
// E -> S7
pub fn __state5<
pub fn __state4<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state8(__lookahead, __tokens, __sym1));
}
Some(Tok::Num(__tok0)) => {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state10(__lookahead, __tokens, __sym1));
__result = try!(__state10(__lookbehind, __lookahead, __tokens, __sym1));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state8(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
}
}
while __sym0.is_some() {
let (__lookahead, __nt) = __result;
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state9(__lookahead, __tokens, __sym1));
__result = try!(__state9(__lookbehind, __lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state7(__lookahead, __tokens, __sym0, __sym1));
__result = try!(__state7(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Ok((__lookahead, __nt));
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 5
// T = "Num" (*) [EOF]
// T = "Num" (*) ["-"]
//
// "-" -> Reduce(T = "Num" => Call(ActionFn(4));)
// EOF -> Reduce(T = "Num" => Call(ActionFn(4));)
//
pub fn __state5<
__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 {
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 6
// E = E "-" (*) T [EOF]
// E = E "-" (*) T ["-"]
@ -286,44 +297,47 @@ mod __parse__S {
// T = (*) "Num" [EOF]
// T = (*) "Num" ["-"]
//
// "(" -> Shift(S5)
// "Num" -> Shift(S4)
// "(" -> Shift(S4)
// "Num" -> Shift(S5)
//
// T -> S11
pub fn __state6<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state5(__lookahead, __tokens, __sym2));
__result = try!(__state4(__lookbehind, __lookahead, __tokens, __sym2));
}
Some(Tok::Num(__tok0)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state4(__lookahead, __tokens, __sym2));
__result = try!(__state5(__lookbehind, __lookahead, __tokens, __sym2));
}
_ => {
return Err(__lookahead);
}
}
while __sym1.is_some() {
let (__lookahead, __nt) = __result;
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym2 = &mut Some(__nt);
__result = try!(__state11(__lookahead, __tokens, __sym0, __sym1, __sym2));
__result = try!(__state11(__lookbehind, __lookahead, __tokens, __sym0, __sym1, __sym2));
}
_ => {
return Ok((__lookahead, __nt));
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
@ -336,29 +350,32 @@ mod __parse__S {
// T = "(" E (*) ")" [EOF]
// T = "(" E (*) ")" ["-"]
//
// "-" -> Shift(S12)
// ")" -> Shift(S13)
// ")" -> Shift(S12)
// "-" -> Shift(S13)
//
pub fn __state7<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::Minus(..)) => {
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state12(__lookahead, __tokens, __sym1, __sym2));
}
Some(__tok @ Tok::RParen(..)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state13(__lookahead, __tokens, __sym0, __sym1, __sym2));
__result = try!(__state12(__lookbehind, __lookahead, __tokens, __sym0, __sym1, __sym2));
}
Some(__tok @ Tok::Minus(..)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state13(__lookbehind, __lookahead, __tokens, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
@ -387,40 +404,43 @@ mod __parse__S {
pub fn __state8<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state8(__lookahead, __tokens, __sym1));
__result = try!(__state8(__lookbehind, __lookahead, __tokens, __sym1));
}
Some(Tok::Num(__tok0)) => {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state10(__lookahead, __tokens, __sym1));
__result = try!(__state10(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
}
}
while __sym0.is_some() {
let (__lookahead, __nt) = __result;
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state9(__lookahead, __tokens, __sym1));
__result = try!(__state9(__lookbehind, __lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state14(__lookahead, __tokens, __sym0, __sym1));
__result = try!(__state14(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Ok((__lookahead, __nt));
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
@ -437,22 +457,23 @@ mod __parse__S {
pub fn __state9<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, 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)));
return Ok((__lookbehind, __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 Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
@ -464,28 +485,29 @@ mod __parse__S {
// T = "Num" (*) [")"]
// T = "Num" (*) ["-"]
//
// ")" -> Reduce(T = "Num" => Call(ActionFn(4));)
// "-" -> Reduce(T = "Num" => Call(ActionFn(4));)
// ")" -> Reduce(T = "Num" => Call(ActionFn(4));)
//
pub fn __state10<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
@ -503,28 +525,29 @@ mod __parse__S {
pub fn __state11<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
__sym1: &mut Option<Tok>,
__sym2: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt)));
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt)));
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
@ -533,6 +556,46 @@ mod __parse__S {
}
// State 12
// T = "(" E ")" (*) [EOF]
// T = "(" E ")" (*) ["-"]
//
// "-" -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
// EOF -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
//
pub fn __state12<
__TOKENS: Iterator<Item=Tok>,
>(
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
__sym2: &mut Option<Tok>,
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Minus(..)) => {
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((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
None => {
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((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 13
// E = E "-" (*) T [")"]
// E = E "-" (*) T ["-"]
// T = (*) "(" E ")" [")"]
@ -544,114 +607,81 @@ mod __parse__S {
// "(" -> Shift(S8)
//
// T -> S15
pub fn __state12<
pub fn __state13<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Num(__tok0)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state10(__lookahead, __tokens, __sym2));
__result = try!(__state10(__lookbehind, __lookahead, __tokens, __sym2));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state8(__lookahead, __tokens, __sym2));
__result = try!(__state8(__lookbehind, __lookahead, __tokens, __sym2));
}
_ => {
return Err(__lookahead);
}
}
while __sym1.is_some() {
let (__lookahead, __nt) = __result;
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym2 = &mut Some(__nt);
__result = try!(__state15(__lookahead, __tokens, __sym0, __sym1, __sym2));
__result = try!(__state15(__lookbehind, __lookahead, __tokens, __sym0, __sym1, __sym2));
}
_ => {
return Ok((__lookahead, __nt));
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 13
// T = "(" E ")" (*) [EOF]
// T = "(" E ")" (*) ["-"]
//
// "-" -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
// EOF -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
//
pub fn __state13<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
__sym2: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Minus(..)) => {
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)));
}
None => {
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);
}
}
}
// State 14
// E = E (*) "-" T [")"]
// E = E (*) "-" T ["-"]
// T = "(" E (*) ")" [")"]
// T = "(" E (*) ")" ["-"]
//
// "-" -> Shift(S12)
// ")" -> Shift(S16)
// "-" -> Shift(S13)
//
pub fn __state14<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::Minus(..)) => {
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state12(__lookahead, __tokens, __sym1, __sym2));
}
Some(__tok @ Tok::RParen(..)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state16(__lookahead, __tokens, __sym0, __sym1, __sym2));
__result = try!(__state16(__lookbehind, __lookahead, __tokens, __sym0, __sym1, __sym2));
}
Some(__tok @ Tok::Minus(..)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state13(__lookbehind, __lookahead, __tokens, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
@ -664,34 +694,35 @@ mod __parse__S {
// E = E "-" T (*) [")"]
// E = E "-" T (*) ["-"]
//
// "-" -> Reduce(E = E, "-", T => Call(ActionFn(2));)
// ")" -> Reduce(E = E, "-", T => Call(ActionFn(2));)
// "-" -> Reduce(E = E, "-", T => Call(ActionFn(2));)
//
pub fn __state15<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
__sym1: &mut Option<Tok>,
__sym2: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::E(__nt)));
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
@ -703,34 +734,35 @@ mod __parse__S {
// T = "(" E ")" (*) [")"]
// T = "(" E ")" (*) ["-"]
//
// "-" -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
// ")" -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
// "-" -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
//
pub fn __state16<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
__sym1: &mut Option<i32>,
__sym2: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Minus(..)) => {
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)));
}
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 Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
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((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);

View File

@ -33,6 +33,7 @@ pub enum GrammarItem {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ExternToken {
pub span: Span,
pub associated_types: Vec<AssociatedType>,
pub enum_token: EnumToken,
}
@ -127,7 +128,14 @@ pub struct Alternative {
pub condition: Option<Condition>,
// => { code }
pub action: Option<String>,
pub action: Option<ActionKind>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ActionKind {
User(String),
Lookahead,
Lookbehind,
}
#[derive(Clone, Debug, PartialEq, Eq)]
@ -181,6 +189,12 @@ pub enum SymbolKind {
// x:X
Name(InternedString, Box<Symbol>),
// @<
Lookahead,
// @>
Lookbehind,
}
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
@ -307,6 +321,10 @@ impl Display for SymbolKind {
write!(fmt, "<{}>", s),
SymbolKind::Name(n, ref s) =>
write!(fmt, "{}:{}", n, s),
SymbolKind::Lookahead =>
write!(fmt, "$<"),
SymbolKind::Lookbehind =>
write!(fmt, "$>"),
}
}
}
@ -468,3 +486,12 @@ impl Path {
}
}
}
impl ActionKind {
pub fn as_user(&self) -> Option<&String> {
match *self {
ActionKind::User(ref s) => Some(s),
_ => None
}
}
}

View File

@ -60,7 +60,7 @@ pub struct Production {
// handy to have it
pub nonterminal: NonterminalString,
pub symbols: Vec<Symbol>,
pub action: ProductionAction,
pub action: ActionKind,
pub span: Span,
}
@ -71,9 +71,11 @@ pub enum Symbol {
}
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum ProductionAction {
pub enum ActionKind {
// execute code provided by the user
Call(ActionFn),
Lookahead,
Lookbehind,
}
#[derive(Clone, PartialEq, Eq)]

View File

@ -2,7 +2,7 @@
//!
//! [recursive ascent]: https://en.wikipedia.org/wiki/Recursive_ascent_parser
use grammar::repr::{Grammar, NonterminalString, ProductionAction, Symbol, TerminalString, Types};
use grammar::repr::{ActionKind, Grammar, NonterminalString, Symbol, TerminalString, Types};
use lr1::{Lookahead, State, StateIndex};
use rust::RustWrite;
use std::io::{self, Write};
@ -117,10 +117,10 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
rust!(self.out, "{{");
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, "match try!({}parse{}::{}state0({}{}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);
rust!(self.out, "({}lookahead, {}parse{}::{}Nonterminal::{}({}nt)) => \
rust!(self.out, "(_, {}lookahead, {}parse{}::{}Nonterminal::{}({}nt)) => \
Ok(({}lookahead, {}nt)),",
self.prefix, self.prefix, self.start_symbol, self.prefix, Escape(self.start_symbol),
self.prefix, self.prefix, self.prefix);
@ -134,6 +134,10 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
fn write_state_fn(&mut self, this_index: StateIndex) -> io::Result<()> {
let this_state = &self.states[this_index.0];
let this_prefix = self.state_prefixes[this_index.0];
let loc_type = match self.types.opt_terminal_loc_type() {
Some(t) => format!("{}", t),
None => format!("()"),
};
let item_type = self.iterator_item_type();
// Leave a comment explaining what this state is.
@ -154,7 +158,8 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
let mut fallthrough = false;
let base_args =
vec![format!("mut {}lookahead: Option<{}>", self.prefix, item_type),
vec![format!("{}lookbehind: Option<{}>", self.prefix, loc_type),
format!("{}lookahead: Option<{}>", self.prefix, item_type),
format!("{}tokens: &mut {}TOKENS", self.prefix, self.prefix)];
let sym_args: Vec<_> =
(0..this_prefix.len())
@ -167,15 +172,17 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
format!("{}state{}", self.prefix, this_index.0),
vec![format!("{}TOKENS: Iterator<Item={}>", self.prefix, item_type)],
base_args.into_iter().chain(sym_args).collect(),
format!("Result<(Option<{}>, {}Nonterminal<{}>), Option<{}>>",
format!("Result<(Option<{}>, Option<{}>, {}Nonterminal<{}>), Option<{}>>",
loc_type,
item_type, self.prefix,
self.grammar.user_type_parameter_refs(),
item_type),
vec![]));
rust!(self.out, "{{");
rust!(self.out, "let mut {}result: (Option<{}>, {}Nonterminal<{}>);",
self.prefix, item_type, self.prefix, self.grammar.user_type_parameter_refs());
rust!(self.out, "let mut {}result: (Option<{}>, Option<{}>, {}Nonterminal<{}>);",
self.prefix, loc_type, item_type, self.prefix,
self.grammar.user_type_parameter_refs());
rust!(self.out, "match {}lookahead {{", self.prefix);
@ -187,7 +194,8 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
match *token {
Lookahead::Terminal(s) => {
let sym_name = format!("{}sym{}", self.prefix, this_prefix.len());
try!(self.consume_terminal(s, sym_name))
let lb_name = format!("{}lookbehind", self.prefix);
try!(self.consume_terminal(s, sym_name, lb_name));
}
Lookahead::EOF =>
unreachable!("should never have to shift EOF")
@ -199,7 +207,7 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
// transition to the new state
let transition =
self.transition(this_prefix, next_index, "lookahead", "tokens");
self.transition(this_prefix, next_index, "lookbehind", "lookahead", "tokens");
rust!(self.out, "{}result = {};", self.prefix, transition);
rust!(self.out, "}}");
@ -230,25 +238,41 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
// invoke the action code
match production.action {
ProductionAction::Call(action_fn) =>
ActionKind::Call(action_fn) => {
rust!(self.out, "let {}nt = super::{}actions::{}action{}({}{});",
self.prefix,
self.prefix,
self.prefix,
action_fn.index(),
self.grammar.user_parameter_refs(),
Sep(", ", &transfer_syms)),
Sep(", ", &transfer_syms))
}
ActionKind::Lookahead => {
debug_assert!(self.types.opt_terminal_loc_type().is_some());
rust!(self.out,
"let {}nt = ::std::clone::Clone(&{}lookahead.map(|o| o.0));",
self.prefix, self.prefix);
}
ActionKind::Lookbehind => {
debug_assert!(self.types.opt_terminal_loc_type().is_some());
rust!(self.out,
"let {}nt = ::std::clone::Clone(&{}lookbehind);",
self.prefix, self.prefix);
}
}
// wrap up the result along with the (unused) lookahead
if !transfer_syms.is_empty() {
// if we popped anything off of the stack, then this frame is done
rust!(self.out, "return Ok(({}lookahead, {}Nonterminal::{}({}nt)));",
self.prefix, self.prefix, Escape(production.nonterminal), self.prefix);
rust!(self.out, "return Ok(({}lookbehind, {}lookahead, {}Nonterminal::{}({}nt)));",
self.prefix, self.prefix, self.prefix,
Escape(production.nonterminal), self.prefix);
} else {
// otherwise, pop back
rust!(self.out, "{}result = ({}lookahead, {}Nonterminal::{}({}nt));",
self.prefix, self.prefix, self.prefix,
rust!(self.out, "{}result = ({}lookbehind, {}lookahead, {}Nonterminal::{}({}nt));",
self.prefix, self.prefix, self.prefix, self.prefix,
Escape(production.nonterminal), self.prefix);
fallthrough = true;
}
@ -271,8 +295,8 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
rust!(self.out, "loop {{");
}
rust!(self.out, "let ({}lookahead, {}nt) = {}result;",
self.prefix, self.prefix, self.prefix);
rust!(self.out, "let ({}lookbehind, {}lookahead, {}nt) = {}result;",
self.prefix, self.prefix, self.prefix, self.prefix);
rust!(self.out, "match {}nt {{", self.prefix);
for (&nt, &next_index) in &this_state.gotos {
@ -280,7 +304,8 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
self.prefix, Escape(nt), self.prefix);
rust!(self.out, "let {}sym{} = &mut Some({}nt);",
self.prefix, this_prefix.len(), self.prefix);
let transition = self.transition(this_prefix, next_index, "lookahead", "tokens");
let transition = self.transition(this_prefix, next_index,
"lookbehind", "lookahead", "tokens");
rust!(self.out, "{}result = {};", self.prefix, transition);
rust!(self.out, "}}");
}
@ -289,7 +314,8 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
// indicates parse successfully completed, so just bail out
if this_state.gotos.len() != self.grammar.productions.keys().len() {
rust!(self.out, "_ => {{");
rust!(self.out, "return Ok(({}lookahead, {}nt));", self.prefix, self.prefix);
rust!(self.out, "return Ok(({}lookbehind, {}lookahead, {}nt));",
self.prefix, self.prefix, self.prefix);
rust!(self.out, "}}");
}
@ -316,6 +342,7 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
fn transition(&self,
prefix: &[Symbol],
next_index: StateIndex,
lookbehind: &str,
lookahead: &str,
tokens: &str)
-> String
@ -332,9 +359,10 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
let transfer_syms = self.pop_syms(n, m);
// invoke next state, transferring the top `m` tokens
format!("try!({}state{}({}{}{}, {}{}, {}))",
format!("try!({}state{}({}{}{}, {}{}, {}{}, {}))",
self.prefix, next_index.0,
self.grammar.user_parameter_refs(),
self.prefix, lookbehind,
self.prefix, lookahead,
self.prefix, tokens,
Sep(", ", &transfer_syms))
@ -356,7 +384,11 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
/// Emit a pattern that matches `id` and extracts its value, storing
/// that value as `let_name`.
fn consume_terminal(&mut self, id: TerminalString, let_name: String) -> io::Result<()> {
fn consume_terminal(&mut self,
id: TerminalString,
let_name: String,
lb_name: String)
-> io::Result<()> {
let mut pattern_names = vec![];
let pattern = self.grammar.pattern(id).map(&mut |_| {
let index = pattern_names.len();
@ -370,10 +402,18 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
pattern = format!("{}tok @ {}", self.prefix, pattern);
}
if self.types.opt_terminal_loc_type().is_some() {
pattern = format!("(_, {}, _)", pattern);
pattern = format!("(_, {}, {}loc)", pattern, self.prefix);
}
rust!(self.out, "Some({}) => {{", pattern);
if self.types.opt_terminal_loc_type().is_some() {
rust!(self.out, "let mut {} = Some({}loc);",
lb_name, self.prefix);
} else {
rust!(self.out, "let mut {} = None;", lb_name);
}
rust!(self.out, "let mut {} = &mut Some(({}));",
let_name, pattern_names.connect(", "));

View File

@ -64,12 +64,12 @@ impl LowerState {
for alt in nt.alternatives {
let nt_type = self.types.nonterminal_type(nt.name).clone();
let symbols = self.symbols(&alt.expr.symbols);
let action_fn = self.action_fn(nt_type, &alt.expr, &symbols, alt.action);
let action = self.action_kind(nt_type, &alt.expr, &symbols, alt.action);
let production = r::Production {
nonterminal: nt.name,
span: alt.span,
symbols: symbols,
action: r::ProductionAction::Call(action_fn),
action: action,
};
self.productions.push(production);
}
@ -129,7 +129,7 @@ impl LowerState {
self.productions.push(r::Production {
nonterminal: fake_name,
symbols: symbols,
action: r::ProductionAction::Call(action_fn),
action: r::ActionKind::Call(action_fn),
span: nt.span
});
(nt.name, fake_name)
@ -137,6 +137,29 @@ impl LowerState {
.collect()
}
fn action_kind(&mut self,
nt_type: r::TypeRepr,
expr: &pt::ExprSymbol,
symbols: &[r::Symbol],
action: Option<pt::ActionKind>)
-> r::ActionKind
{
match action {
Some(pt::ActionKind::Lookahead) =>
r::ActionKind::Lookahead,
Some(pt::ActionKind::Lookbehind) =>
r::ActionKind::Lookbehind,
Some(pt::ActionKind::User(string)) => {
let action_fn = self.action_fn(nt_type, &expr, &symbols, Some(string));
r::ActionKind::Call(action_fn)
}
None => {
let action_fn = self.action_fn(nt_type, &expr, &symbols, None);
r::ActionKind::Call(action_fn)
}
}
}
fn action_fn(&mut self,
nt_type: r::TypeRepr,
expr: &pt::ExprSymbol,
@ -209,7 +232,11 @@ impl LowerState {
pt::SymbolKind::Nonterminal(id) => r::Symbol::Nonterminal(id),
pt::SymbolKind::Choose(ref s) | pt::SymbolKind::Name(_, ref s) => self.symbol(s),
pt::SymbolKind::Macro(..) | pt::SymbolKind::Repeat(..) | pt::SymbolKind::Expr(..) => {
pt::SymbolKind::Macro(..) |
pt::SymbolKind::Repeat(..) |
pt::SymbolKind::Expr(..) |
pt::SymbolKind::Lookahead |
pt::SymbolKind::Lookbehind => {
unreachable!("symbol `{}` should have been normalized away by now", symbol)
}
}
@ -259,6 +286,7 @@ fn find_prefix(grammar: &pt::Grammar) -> String {
.filter_map(|i| i.as_nonterminal())
.flat_map(|nt| nt.alternatives.iter())
.filter_map(|alt| alt.action.as_ref())
.filter_map(|action| action.as_user())
.any(|s| s.contains(&prefix))
||
grammar.items
@ -271,3 +299,4 @@ fn find_prefix(grammar: &pt::Grammar) -> String {
prefix
}

View File

@ -1,6 +1,6 @@
use std::collections::{HashMap, HashSet};
use intern::{intern, read, InternedString};
use grammar::parse_tree::{Alternative,
use grammar::parse_tree::{ActionKind, Alternative,
Condition, ConditionOp,
ExprSymbol,
Grammar, GrammarItem,
@ -77,6 +77,10 @@ impl MacroExpander {
items.push(try!(self.expand_expr_symbol(sym.span, expr))),
SymbolKind::Repeat(repeat) =>
items.push(try!(self.expand_repeat_symbol(sym.span, *repeat))),
SymbolKind::Lookahead =>
items.push(try!(self.expand_lookahead_symbol(sym.span))),
SymbolKind::Lookbehind =>
items.push(try!(self.expand_lookbehind_symbol(sym.span))),
_ =>
assert!(false, "don't know how to expand `{:?}`", sym)
}
@ -128,6 +132,8 @@ impl MacroExpander {
self.replace_symbol(sym);
return;
}
SymbolKind::Lookahead | SymbolKind::Lookbehind => {
}
}
// only symbols we intend to expand fallthrough to here
@ -307,6 +313,10 @@ impl MacroExpander {
SymbolKind::Choose(Box::new(self.macro_expand_symbol(args, sym))),
SymbolKind::Name(id, ref sym) =>
SymbolKind::Name(id, Box::new(self.macro_expand_symbol(args, sym))),
SymbolKind::Lookahead =>
SymbolKind::Lookahead,
SymbolKind::Lookbehind =>
SymbolKind::Lookbehind,
};
Symbol { span: symbol.span, kind: kind }
@ -343,7 +353,7 @@ impl MacroExpander {
alternatives: vec![Alternative { span: span,
expr: expr,
condition: None,
action: Some(format!("(<>)")) }]
action: action("(<>)") }]
}))
}
@ -374,7 +384,7 @@ impl MacroExpander {
span: span,
expr: ExprSymbol { symbols: vec![] },
condition: None,
action: Some(format!("vec![]"))
action: action("vec![]")
},
// X* = <v:X+> <e:X>
@ -396,7 +406,7 @@ impl MacroExpander {
Box::new(repeat.symbol.clone())))]
},
condition: None,
action: Some(format!("{{ let mut v = v; v.push(e); v }}"))
action: action("{ let mut v = v; v.push(e); v }")
}],
}))
}
@ -419,7 +429,7 @@ impl MacroExpander {
symbols: vec![repeat.symbol.clone()]
},
condition: None,
action: Some(format!("vec![<>]"))
action: action("Vec![<>]"),
},
// X+ = <v:X+> <e:X>
@ -434,7 +444,7 @@ impl MacroExpander {
e, Box::new(repeat.symbol.clone())))]
},
condition: None,
action: Some(format!("{{ let mut v = v; v.push(e); v }}"))
action: action("{ let mut v = v; v.push(e); v }"),
}],
}))
}
@ -456,7 +466,7 @@ impl MacroExpander {
symbols: vec![repeat.symbol.clone()]
},
condition: None,
action: Some(format!("Some(<>)")) },
action: action("Some(<>)") },
// X? = { => None; }
Alternative { span: span,
@ -464,11 +474,19 @@ impl MacroExpander {
symbols: vec![]
},
condition: None,
action: Some(format!("None")) }]
action: action("None") }]
}))
}
}
}
fn expand_lookahead_symbol(&mut self, _span: Span) -> NormResult<GrammarItem> {
panic!("not yet implemented")
}
fn expand_lookbehind_symbol(&mut self, _span: Span) -> NormResult<GrammarItem> {
panic!("not yet implemented")
}
}
fn maybe_tuple(v: Vec<TypeRef>) -> TypeRef {
@ -478,3 +496,7 @@ fn maybe_tuple(v: Vec<TypeRef>) -> TypeRef {
TypeRef::Tuple(v)
}
}
fn action(s: &str) -> Option<ActionKind> {
Some(ActionKind::User(s.to_string()))
}

View File

@ -1,9 +1,9 @@
use intern::InternedString;
use grammar::parse_tree::{Alternative, ExprSymbol, Symbol, SymbolKind};
use grammar::parse_tree::{ActionKind, Alternative, ExprSymbol, Symbol, SymbolKind};
#[derive(Debug)]
pub enum AlternativeAction<'a> {
User(&'a str),
User(&'a ActionKind),
Default(Symbols<'a>),
}

View File

@ -252,7 +252,8 @@ impl<'grammar> TypeInferencer<'grammar> {
SymbolKind::Choose(ref s) => self.symbol_type(&s.kind),
SymbolKind::Name(_, ref s) => self.symbol_type(&s.kind),
SymbolKind::Repeat(..) | SymbolKind::Expr(..) | SymbolKind::Macro(..) => {
SymbolKind::Repeat(..) | SymbolKind::Expr(..) | SymbolKind::Macro(..) |
SymbolKind::Lookahead | SymbolKind::Lookbehind => {
unreachable!("symbol `{:?}` should have been expanded away", symbol)
}
}

View File

@ -25,6 +25,12 @@ pub fn validate(grammar: &Grammar) -> NormResult<()> {
.collect()
};
let extern_token: Option<&ExternToken> =
grammar.items
.iter()
.filter_map(|item| item.as_extern_token())
.next();
let conversions: Set<_> =
grammar.items
.iter()
@ -35,6 +41,7 @@ pub fn validate(grammar: &Grammar) -> NormResult<()> {
let validator = Validator {
grammar: grammar,
globals: globals,
extern_token: extern_token,
conversions: conversions,
};
@ -43,6 +50,7 @@ pub fn validate(grammar: &Grammar) -> NormResult<()> {
struct Validator<'grammar> {
grammar: &'grammar Grammar,
extern_token: Option<&'grammar ExternToken>,
globals: ScopeChain<'grammar>,
conversions: Set<TerminalString>,
}
@ -65,6 +73,12 @@ impl<'grammar> Validator<'grammar> {
match *item {
GrammarItem::Use(..) => { }
GrammarItem::ExternToken(ref data) => {
if data.span != self.extern_token.unwrap().span {
return_err!(
data.span,
"multiple extern token definitions are not permitted");
}
let allowed_names = vec![intern(LOCATION)];
let mut new_names = set();
for associated_type in &data.associated_types {
@ -238,6 +252,23 @@ impl<'grammar> Validator<'grammar> {
SymbolKind::Choose(ref sym) | SymbolKind::Name(_, ref sym) => {
try!(self.validate_symbol(scope, sym));
}
SymbolKind::Lookahead | SymbolKind::Lookbehind => {
if self.extern_token.is_none() {
return_err!(symbol.span,
"lookahead/lookbehind not permitted without \
an extern token declaration");
}
let loc = intern(LOCATION);
if self.extern_token.unwrap().associated_type(loc).is_none() {
return_err!(
symbol.span,
"lookahead/lookbehind require you to declare the type of \
a location; add a `type {} = ..` statement to the extern token \
block",
LOCATION);
}
}
}
Ok(())

View File

@ -9,7 +9,7 @@ fn check_err(expected_err: &str, grammar: &str) {
// indicate the span where an error is expected.
let start_index = grammar.find(">>>").unwrap();
let grammar = grammar.replace(">>>", ""); // remove the `>>>` marker
let end_index = grammar.find("<<<").unwrap();
let end_index = grammar.rfind("<<<").unwrap();
let grammar = grammar.replace("<<<", "");
assert!(start_index <= end_index);
@ -71,3 +71,17 @@ fn dup_assoc_type() {
type >>>Location <<<= u32;
enum Tok { } }"#);
}
#[test]
fn lookahead_without_loc_type() {
check_err(
r#"lookahead/lookbehind require you to declare the type of a location"#,
r#"grammar; extern token { enum Tok { } } Foo = >>>@<<<<;"#);
}
#[test]
fn multiple_extern_token() {
check_err(
r#"multiple extern token definitions are not permitted"#,
r#"grammar; extern token { enum Tok { } } >>>extern token <<<{ enum Tok { } }"#);
}

View File

@ -110,7 +110,16 @@ rusty_peg! {
IF_COND: Condition =
("if" <c:COND>) => c;
ACTION: String = ("=>" <b:CODE>) => b;
ACTION: ActionKind = (LOOKAHEAD_ACTION / LOOKBEHIND_ACTION / USER_ACTION);
USER_ACTION: ActionKind =
("=>" <b:CODE>) => ActionKind::User(b);
LOOKAHEAD_ACTION: ActionKind =
("=>@<") => ActionKind::Lookahead;
LOOKBEHIND_ACTION: ActionKind =
("=>@>") => ActionKind::Lookbehind;
// Conditions
@ -154,7 +163,8 @@ rusty_peg! {
REPEAT_OP_QUESTION: RepeatOp = "?" => RepeatOp::Question;
SYMBOL1: Symbol =
(MACRO_SYMBOL / TERMINAL_SYMBOL / NT_SYMBOL / ESCAPE_SYMBOL / PAREN_SYMBOL);
(MACRO_SYMBOL / TERMINAL_SYMBOL / NT_SYMBOL / ESCAPE_SYMBOL / PAREN_SYMBOL/
LOOKAHEAD_SYMBOL / LOOKBEHIND_SYMBOL);
MACRO_SYMBOL: Symbol =
(<lo:POSL> <l:MACRO_ID> <m:{SYMBOL ","}> <n:[SYMBOL]> ">" <hi:POSR>) => {
@ -183,6 +193,16 @@ rusty_peg! {
Symbol::new(Span(lo, hi), SymbolKind::Expr(s))
};
LOOKAHEAD_SYMBOL: Symbol =
(<lo:POSL> "@<" <hi:POSR>) => {
Symbol::new(Span(lo, hi), SymbolKind::Lookahead)
};
LOOKBEHIND_SYMBOL: Symbol =
(<lo:POSL> "@>" <hi:POSR>) => {
Symbol::new(Span(lo, hi), SymbolKind::Lookbehind)
};
EXPR_SYMBOL: ExprSymbol =
(<s:{SYMBOL}>) => ExprSymbol { symbols: s };
@ -247,7 +267,7 @@ rusty_peg! {
// TOKEN DEFINITIONS
EXTERN_TOKEN: GrammarItem =
("extern" "token" "{"
(<lo0:POSL> "extern" "token" <hi0:POSR> "{"
<a0:{ASSOCIATED_TYPE}>
"enum" <lo:POSL> <t:TYPE_REF> <hi:POSR> "{"
<c0:{CONVERSION ","}> <c1:[CONVERSION]>
@ -255,6 +275,7 @@ rusty_peg! {
<a1:{ASSOCIATED_TYPE}>
"}") => {
GrammarItem::ExternToken(ExternToken {
span: Span(lo0, hi0),
associated_types: a0.into_iter().chain(a1).collect(),
enum_token: EnumToken {
type_name: t,

View File

@ -124,6 +124,12 @@ fn macro_symbols() {
assert!(super::parse_symbol(r#"Foo <Baz>"#).is_err());
}
#[test]
fn lookaround() {
super::parse_symbol(r#"@<"#).unwrap();
super::parse_symbol(r#"@>"#).unwrap();
}
#[test]
fn symbol_precedence() {
// check that we parse this as choosing a X+