mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-03-16 17:00:53 +00:00
thread through most of the work to support lookahead/lookbehind,
but not the actual expansion (untested, clearly)
This commit is contained in:
parent
fad838a361
commit
f758e0ff00
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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(", "));
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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()))
|
||||
}
|
||||
|
@ -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>),
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
|
@ -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 { } }"#);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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+
|
||||
|
Loading…
x
Reference in New Issue
Block a user