get lookahead/lookbehind working, and add a test to laprpop-test for it

This commit is contained in:
Niko Matsakis 2015-07-18 18:14:39 -04:00
parent f758e0ff00
commit 6da930bbf6
14 changed files with 4207 additions and 3664 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
use util::tok::Tok;
grammar;
extern token {
type Location = usize;
enum Tok {
"-" => Tok::Minus(..),
"+" => Tok::Plus(..)
}
}
pub Items: Vec<(Option<usize>, Option<usize>)> = {
=> vec![];
<v:Items> <e:Spanned<"+">> => {
let mut v = v;
v.push(e);
v
};
<v:Items> "-" => v;
};
Spanned<T>: (Option<usize>, Option<usize>) = {
<@<> T <@>> => (<>);
};

434
lalrpop-test/src/loc.rs Normal file
View File

@ -0,0 +1,434 @@
#![allow(unused_imports)]
use util::tok::Tok;
#[allow(non_snake_case)]
pub fn parse_Items<
__TOKENS: IntoIterator<Item=(usize,Tok,usize)>,
>(
__tokens: __TOKENS,
) -> Result<(Option<(usize,Tok,usize)>, Vec<(Option<usize>, Option<usize>)>), Option<(usize,Tok,usize)>>
{
let mut __tokens = __tokens.into_iter();
let __lookahead = __tokens.next();
match try!(__parse__Items::__state0(None, __lookahead, &mut __tokens)) {
(_, __lookahead, __parse__Items::__Nonterminal::____Items(__nt)) => Ok((__lookahead, __nt)),
_ => unreachable!(),
}
}
mod __parse__Items {
#![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports)]
use util::tok::Tok;
pub enum __Nonterminal<> {
____Items(Vec<(Option<usize>, Option<usize>)>),
_40_3c(::std::option::Option<usize>),
Spanned_3c_22_2b_22_3e((Option<usize>, Option<usize>)),
Items(Vec<(Option<usize>, Option<usize>)>),
_40_3e(::std::option::Option<usize>),
}
// State 0
// Items = (*) [EOF]
// Items = (*) ["+"]
// Items = (*) ["-"]
// Items = (*) Items Spanned<"+"> [EOF]
// Items = (*) Items Spanned<"+"> ["+"]
// Items = (*) Items Spanned<"+"> ["-"]
// Items = (*) Items "-" [EOF]
// Items = (*) Items "-" ["+"]
// Items = (*) Items "-" ["-"]
// __Items = (*) Items [EOF]
//
// EOF -> Reduce(Items = => Call(ActionFn(1));)
// "-" -> Reduce(Items = => Call(ActionFn(1));)
// "+" -> Reduce(Items = => Call(ActionFn(1));)
//
// Items -> S1
pub fn __state0<
__TOKENS: Iterator<Item=(usize,Tok,usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize,Tok,usize)>,
__tokens: &mut __TOKENS,
) -> Result<(Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>), Option<(usize,Tok,usize)>>
{
let mut __result: (Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>);
match __lookahead {
None => {
let __nt = super::__actions::__action1();
__result = (__lookbehind, __lookahead, __Nonterminal::Items(__nt));
}
Some((_, Tok::Minus(..), _)) => {
let __nt = super::__actions::__action1();
__result = (__lookbehind, __lookahead, __Nonterminal::Items(__nt));
}
Some((_, Tok::Plus(..), _)) => {
let __nt = super::__actions::__action1();
__result = (__lookbehind, __lookahead, __Nonterminal::Items(__nt));
}
_ => {
return Err(__lookahead);
}
}
loop {
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::Items(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state1(__lookbehind, __lookahead, __tokens, __sym0));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
}
// State 1
// @< = (*) ["+"]
// Items = Items (*) Spanned<"+"> [EOF]
// Items = Items (*) Spanned<"+"> ["+"]
// Items = Items (*) Spanned<"+"> ["-"]
// Items = Items (*) "-" [EOF]
// Items = Items (*) "-" ["+"]
// Items = Items (*) "-" ["-"]
// Spanned<"+"> = (*) @< "+" @> [EOF]
// Spanned<"+"> = (*) @< "+" @> ["+"]
// Spanned<"+"> = (*) @< "+" @> ["-"]
// __Items = Items (*) [EOF]
//
// "+" -> Reduce(@< = => Lookahead;)
// EOF -> Reduce(__Items = Items => Call(ActionFn(0));)
// "-" -> Shift(S4)
//
// @< -> S2
// Spanned<"+"> -> S3
pub fn __state1<
__TOKENS: Iterator<Item=(usize,Tok,usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize,Tok,usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Vec<(Option<usize>, Option<usize>)>>,
) -> Result<(Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>), Option<(usize,Tok,usize)>>
{
let mut __result: (Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>);
match __lookahead {
Some((_, __tok @ Tok::Minus(..), __loc)) => {
let mut __lookbehind = Some(__loc);
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state4(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
Some((_, Tok::Plus(..), _)) => {
let __nt = __lookahead.as_ref().map(|o| ::std::clone::Clone::clone(&o.0));
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3c(__nt));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action0(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::____Items(__nt)));
}
_ => {
return Err(__lookahead);
}
}
while __sym0.is_some() {
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::_40_3c(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state2(__lookbehind, __lookahead, __tokens, __sym1));
}
__Nonterminal::Spanned_3c_22_2b_22_3e(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state3(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 2
// Spanned<"+"> = @< (*) "+" @> [EOF]
// Spanned<"+"> = @< (*) "+" @> ["+"]
// Spanned<"+"> = @< (*) "+" @> ["-"]
//
// "+" -> Shift(S5)
//
pub fn __state2<
__TOKENS: Iterator<Item=(usize,Tok,usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize,Tok,usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<::std::option::Option<usize>>,
) -> Result<(Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>), Option<(usize,Tok,usize)>>
{
let mut __result: (Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>);
match __lookahead {
Some((_, __tok @ Tok::Plus(..), __loc)) => {
let mut __lookbehind = Some(__loc);
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state5(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 3
// Items = Items Spanned<"+"> (*) [EOF]
// Items = Items Spanned<"+"> (*) ["+"]
// Items = Items Spanned<"+"> (*) ["-"]
//
// "-" -> Reduce(Items = Items, Spanned<"+"> => Call(ActionFn(2));)
// "+" -> Reduce(Items = Items, Spanned<"+"> => Call(ActionFn(2));)
// EOF -> Reduce(Items = Items, Spanned<"+"> => Call(ActionFn(2));)
//
pub fn __state3<
__TOKENS: Iterator<Item=(usize,Tok,usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize,Tok,usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Vec<(Option<usize>, Option<usize>)>>,
__sym1: &mut Option<(Option<usize>, Option<usize>)>,
) -> Result<(Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>), Option<(usize,Tok,usize)>>
{
let mut __result: (Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>);
match __lookahead {
Some((_, Tok::Minus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__actions::__action2(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 4
// Items = Items "-" (*) [EOF]
// Items = Items "-" (*) ["+"]
// Items = Items "-" (*) ["-"]
//
// EOF -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
// "+" -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
// "-" -> Reduce(Items = Items, "-" => Call(ActionFn(3));)
//
pub fn __state4<
__TOKENS: Iterator<Item=(usize,Tok,usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize,Tok,usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Vec<(Option<usize>, Option<usize>)>>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>), Option<(usize,Tok,usize)>>
{
let mut __result: (Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__actions::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__actions::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
Some((_, Tok::Minus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __nt = super::__actions::__action3(__sym0, __sym1);
return Ok((__lookbehind, __lookahead, __Nonterminal::Items(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 5
// @> = (*) [EOF]
// @> = (*) ["+"]
// @> = (*) ["-"]
// Spanned<"+"> = @< "+" (*) @> [EOF]
// Spanned<"+"> = @< "+" (*) @> ["+"]
// Spanned<"+"> = @< "+" (*) @> ["-"]
//
// EOF -> Reduce(@> = => Lookbehind;)
// "-" -> Reduce(@> = => Lookbehind;)
// "+" -> Reduce(@> = => Lookbehind;)
//
// @> -> S6
pub fn __state5<
__TOKENS: Iterator<Item=(usize,Tok,usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize,Tok,usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<::std::option::Option<usize>>,
__sym1: &mut Option<Tok>,
) -> Result<(Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>), Option<(usize,Tok,usize)>>
{
let mut __result: (Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>);
match __lookahead {
None => {
let __nt = ::std::clone::Clone::clone(&__lookbehind);
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
Some((_, Tok::Minus(..), _)) => {
let __nt = ::std::clone::Clone::clone(&__lookbehind);
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
Some((_, Tok::Plus(..), _)) => {
let __nt = ::std::clone::Clone::clone(&__lookbehind);
__result = (__lookbehind, __lookahead, __Nonterminal::_40_3e(__nt));
}
_ => {
return Err(__lookahead);
}
}
while __sym1.is_some() {
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::_40_3e(__nt) => {
let __sym2 = &mut Some(__nt);
__result = try!(__state6(__lookbehind, __lookahead, __tokens, __sym0, __sym1, __sym2));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 6
// Spanned<"+"> = @< "+" @> (*) [EOF]
// Spanned<"+"> = @< "+" @> (*) ["+"]
// Spanned<"+"> = @< "+" @> (*) ["-"]
//
// EOF -> Reduce(Spanned<"+"> = @<, "+", @> => Call(ActionFn(4));)
// "-" -> Reduce(Spanned<"+"> = @<, "+", @> => Call(ActionFn(4));)
// "+" -> Reduce(Spanned<"+"> = @<, "+", @> => Call(ActionFn(4));)
//
pub fn __state6<
__TOKENS: Iterator<Item=(usize,Tok,usize)>,
>(
__lookbehind: Option<usize>,
__lookahead: Option<(usize,Tok,usize)>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<::std::option::Option<usize>>,
__sym1: &mut Option<Tok>,
__sym2: &mut Option<::std::option::Option<usize>>,
) -> Result<(Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>), Option<(usize,Tok,usize)>>
{
let mut __result: (Option<usize>, Option<(usize,Tok,usize)>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action4(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::Spanned_3c_22_2b_22_3e(__nt)));
}
Some((_, Tok::Minus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action4(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::Spanned_3c_22_2b_22_3e(__nt)));
}
Some((_, Tok::Plus(..), _)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action4(__sym0, __sym1, __sym2);
return Ok((__lookbehind, __lookahead, __Nonterminal::Spanned_3c_22_2b_22_3e(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
}
mod __actions {
use util::tok::Tok;
pub fn __action0<
>(
__0: Vec<(Option<usize>, Option<usize>)>,
) -> Vec<(Option<usize>, Option<usize>)>
{
(__0)
}
pub fn __action1<
>(
) -> Vec<(Option<usize>, Option<usize>)>
{
vec![]
}
pub fn __action2<
>(
v: Vec<(Option<usize>, Option<usize>)>,
e: (Option<usize>, Option<usize>),
) -> Vec<(Option<usize>, Option<usize>)>
{
{
let mut v = v;
v.push(e);
v
}
}
pub fn __action3<
>(
v: Vec<(Option<usize>, Option<usize>)>,
_: Tok,
) -> Vec<(Option<usize>, Option<usize>)>
{
v
}
pub fn __action4<
>(
__0: ::std::option::Option<usize>,
_: Tok,
__1: ::std::option::Option<usize>,
) -> (Option<usize>, Option<usize>)
{
(__0, __1)
}
}

View File

@ -1,6 +1,7 @@
mod expr;
mod expr_arena;
mod expr_arena_ast;
mod loc;
mod sub;
mod util;
@ -70,3 +71,18 @@ fn expr_arena_test2() {
util::test_loc(|v| expr_arena::parse_Expr(&arena, v), "*(22, 3, 6,)", expected);
}
#[test]
fn loc_test1() {
let expected = vec![(Some(4), Some(5)),
(Some(8), Some(9)),
(Some(16), Some(17))];
util::test_loc(|v| loc::parse_Items(v), "--+-+---+", expected);
// 000001111
// 024680246
}
#[test]
fn loc_test2() {
util::test_loc(|v| loc::parse_Items(v), "+", vec![(Some(0), Some(1))]);
}

View File

@ -22,10 +22,10 @@ mod __parse__S {
use util::tok::Tok;
pub enum __Nonterminal<> {
____S(i32),
T(i32),
S(i32),
E(i32),
____S(i32),
}
// State 0
@ -40,12 +40,12 @@ mod __parse__S {
// T = (*) "Num" ["-"]
// __S = (*) S [EOF]
//
// "(" -> Shift(S4)
// "Num" -> Shift(S5)
// "Num" -> Shift(S1)
// "(" -> Shift(S5)
//
// T -> S3
// T -> S4
// S -> S2
// E -> S1
// E -> S3
pub fn __state0<
__TOKENS: Iterator<Item=Tok>,
>(
@ -56,16 +56,16 @@ mod __parse__S {
{
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym0 = &mut Some((__tok));
let __lookahead = __tokens.next();
__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!(__state1(__lookbehind, __lookahead, __tokens, __sym0));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym0 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state5(__lookbehind, __lookahead, __tokens, __sym0));
}
_ => {
@ -77,7 +77,7 @@ mod __parse__S {
match __nt {
__Nonterminal::T(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state3(__lookbehind, __lookahead, __tokens, __sym0));
__result = try!(__state4(__lookbehind, __lookahead, __tokens, __sym0));
}
__Nonterminal::S(__nt) => {
let __sym0 = &mut Some(__nt);
@ -85,7 +85,7 @@ mod __parse__S {
}
__Nonterminal::E(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state1(__lookbehind, __lookahead, __tokens, __sym0));
__result = try!(__state3(__lookbehind, __lookahead, __tokens, __sym0));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
@ -95,12 +95,11 @@ mod __parse__S {
}
// State 1
// E = E (*) "-" T [EOF]
// E = E (*) "-" T ["-"]
// S = E (*) [EOF]
// T = "Num" (*) [EOF]
// T = "Num" (*) ["-"]
//
// EOF -> Reduce(S = E => Call(ActionFn(1));)
// "-" -> Shift(S6)
// EOF -> Reduce(T = "Num" => Call(ActionFn(4));)
// "-" -> Reduce(T = "Num" => Call(ActionFn(4));)
//
pub fn __state1<
__TOKENS: Iterator<Item=Tok>,
@ -113,22 +112,20 @@ mod __parse__S {
{
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::__action1(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::S(__nt)));
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 2
@ -159,11 +156,12 @@ mod __parse__S {
}
// State 3
// 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));)
// "-" -> Shift(S6)
// EOF -> Reduce(S = E => Call(ActionFn(1));)
//
pub fn __state3<
__TOKENS: Iterator<Item=Tok>,
@ -176,12 +174,48 @@ mod __parse__S {
{
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::__action1(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::S(__nt)));
}
_ => {
return Err(__lookahead);
}
}
return Ok(__result);
}
// State 4
// E = T (*) [EOF]
// E = T (*) ["-"]
//
// "-" -> Reduce(E = T => Call(ActionFn(3));)
// EOF -> Reduce(E = T => Call(ActionFn(3));)
//
pub fn __state4<
__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::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
@ -192,7 +226,7 @@ mod __parse__S {
}
}
// State 4
// State 5
// E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"]
// E = (*) T [")"]
@ -204,12 +238,12 @@ mod __parse__S {
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "Num" -> Shift(S10)
// "(" -> Shift(S8)
// "Num" -> Shift(S9)
// "(" -> Shift(S10)
//
// T -> S9
// E -> S7
pub fn __state4<
// E -> S8
// T -> S7
pub fn __state5<
__TOKENS: Iterator<Item=Tok>,
>(
__lookbehind: Option<()>,
@ -224,13 +258,13 @@ mod __parse__S {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state10(__lookbehind, __lookahead, __tokens, __sym1));
__result = try!(__state9(__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));
__result = try!(__state10(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
@ -239,13 +273,13 @@ mod __parse__S {
while __sym0.is_some() {
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state9(__lookbehind, __lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state7(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
__result = try!(__state8(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state7(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
@ -255,40 +289,6 @@ mod __parse__S {
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 ["-"]
@ -297,8 +297,8 @@ mod __parse__S {
// T = (*) "Num" [EOF]
// T = (*) "Num" ["-"]
//
// "(" -> Shift(S4)
// "Num" -> Shift(S5)
// "Num" -> Shift(S1)
// "(" -> Shift(S5)
//
// T -> S11
pub fn __state6<
@ -313,16 +313,16 @@ mod __parse__S {
{
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!(__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!(__state1(__lookbehind, __lookahead, __tokens, __sym2));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state5(__lookbehind, __lookahead, __tokens, __sym2));
}
_ => {
@ -345,15 +345,49 @@ mod __parse__S {
}
// State 7
// E = T (*) [")"]
// E = T (*) ["-"]
//
// "-" -> Reduce(E = T => Call(ActionFn(3));)
// ")" -> Reduce(E = T => Call(ActionFn(3));)
//
pub fn __state7<
__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::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 8
// E = E (*) "-" T [")"]
// E = E (*) "-" T ["-"]
// T = "(" E (*) ")" [EOF]
// T = "(" E (*) ")" ["-"]
//
// ")" -> Shift(S12)
// "-" -> Shift(S13)
// ")" -> Shift(S13)
// "-" -> Shift(S12)
//
pub fn __state7<
pub fn __state8<
__TOKENS: Iterator<Item=Tok>,
>(
__lookbehind: Option<()>,
@ -369,13 +403,13 @@ mod __parse__S {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state12(__lookbehind, __lookahead, __tokens, __sym0, __sym1, __sym2));
__result = try!(__state13(__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));
__result = try!(__state12(__lookbehind, __lookahead, __tokens, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
@ -384,75 +418,12 @@ mod __parse__S {
return Ok(__result);
}
// State 8
// E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"]
// E = (*) T [")"]
// E = (*) T ["-"]
// T = (*) "(" E ")" [")"]
// T = (*) "(" E ")" ["-"]
// T = "(" (*) E ")" [")"]
// T = "(" (*) E ")" ["-"]
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "(" -> Shift(S8)
// "Num" -> Shift(S10)
//
// T -> S9
// E -> S14
pub fn __state8<
__TOKENS: Iterator<Item=Tok>,
>(
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
) -> Result<(Option<()>, Option<Tok>, __Nonterminal<>), Option<Tok>>
{
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(__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(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
}
}
while __sym0.is_some() {
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state9(__lookbehind, __lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state14(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 9
// E = T (*) [")"]
// E = T (*) ["-"]
// T = "Num" (*) [")"]
// T = "Num" (*) ["-"]
//
// ")" -> Reduce(E = T => Call(ActionFn(3));)
// "-" -> Reduce(E = T => Call(ActionFn(3));)
// ")" -> Reduce(T = "Num" => Call(ActionFn(4));)
// "-" -> Reduce(T = "Num" => Call(ActionFn(4));)
//
pub fn __state9<
__TOKENS: Iterator<Item=Tok>,
@ -467,13 +438,13 @@ mod __parse__S {
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::E(__nt)));
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
@ -482,45 +453,74 @@ mod __parse__S {
}
// State 10
// T = "Num" (*) [")"]
// T = "Num" (*) ["-"]
// E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"]
// E = (*) T [")"]
// E = (*) T ["-"]
// T = (*) "(" E ")" [")"]
// T = (*) "(" E ")" ["-"]
// T = "(" (*) E ")" [")"]
// T = "(" (*) E ")" ["-"]
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "-" -> Reduce(T = "Num" => Call(ActionFn(4));)
// ")" -> Reduce(T = "Num" => Call(ActionFn(4));)
// "(" -> Shift(S10)
// "Num" -> Shift(S9)
//
// E -> S14
// T -> S7
pub fn __state10<
__TOKENS: Iterator<Item=Tok>,
>(
__lookbehind: Option<()>,
__lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
__sym0: &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 __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
Some(__tok @ Tok::LParen(..)) => {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state10(__lookbehind, __lookahead, __tokens, __sym1));
}
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookbehind, __lookahead, __Nonterminal::T(__nt)));
Some(Tok::Num(__tok0)) => {
let mut __lookbehind = None;
let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state9(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
}
}
while __sym0.is_some() {
let (__lookbehind, __lookahead, __nt) = __result;
match __nt {
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state14(__lookbehind, __lookahead, __tokens, __sym0, __sym1));
}
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state7(__lookbehind, __lookahead, __tokens, __sym1));
}
_ => {
return Ok((__lookbehind, __lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 11
// E = E "-" T (*) [EOF]
// E = E "-" T (*) ["-"]
//
// EOF -> Reduce(E = E, "-", T => Call(ActionFn(2));)
// "-" -> Reduce(E = E, "-", T => Call(ActionFn(2));)
// EOF -> Reduce(E = E, "-", T => Call(ActionFn(2));)
//
pub fn __state11<
__TOKENS: Iterator<Item=Tok>,
@ -535,14 +535,14 @@ mod __parse__S {
{
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
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)));
}
Some(Tok::Minus(..)) => {
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
@ -556,46 +556,6 @@ 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 ")" [")"]
@ -603,11 +563,11 @@ mod __parse__S {
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "Num" -> Shift(S10)
// "(" -> Shift(S8)
// "(" -> Shift(S10)
// "Num" -> Shift(S9)
//
// T -> S15
pub fn __state13<
pub fn __state12<
__TOKENS: Iterator<Item=Tok>,
>(
__lookbehind: Option<()>,
@ -619,17 +579,17 @@ mod __parse__S {
{
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(__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(__lookbehind, __lookahead, __tokens, __sym2));
__result = try!(__state10(__lookbehind, __lookahead, __tokens, __sym2));
}
Some(Tok::Num(__tok0)) => {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state9(__lookbehind, __lookahead, __tokens, __sym2));
}
_ => {
return Err(__lookahead);
@ -650,6 +610,46 @@ mod __parse__S {
return Ok(__result);
}
// State 13
// T = "(" E ")" (*) [EOF]
// T = "(" E ")" (*) ["-"]
//
// EOF -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
// "-" -> Reduce(T = "(", E, ")" => Call(ActionFn(5));)
//
pub fn __state13<
__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 {
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)));
}
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);
}
}
}
// State 14
// E = E (*) "-" T [")"]
// E = E (*) "-" T ["-"]
@ -657,7 +657,7 @@ mod __parse__S {
// T = "(" E (*) ")" ["-"]
//
// ")" -> Shift(S16)
// "-" -> Shift(S13)
// "-" -> Shift(S12)
//
pub fn __state14<
__TOKENS: Iterator<Item=Tok>,
@ -681,7 +681,7 @@ mod __parse__S {
let mut __lookbehind = None;
let mut __sym2 = &mut Some((__tok));
let __lookahead = __tokens.next();
__result = try!(__state13(__lookbehind, __lookahead, __tokens, __sym1, __sym2));
__result = try!(__state12(__lookbehind, __lookahead, __tokens, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
@ -694,8 +694,8 @@ 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>,
@ -710,14 +710,14 @@ mod __parse__S {
{
let mut __result: (Option<()>, Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::RParen(..)) => {
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)));
}
Some(Tok::Minus(..)) => {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();

View File

@ -15,24 +15,23 @@ pub enum Tok {
// simplest and stupidest possible tokenizer
pub fn tokenize(s: &str) -> Vec<(usize, Tok, usize)> {
let mut tokens = vec![];
let mut chars = s.char_indices();
let mut chars = s.chars();
let mut lookahead = chars.next();
while let Some((pos, c)) = lookahead {
while let Some(c) = lookahead {
// skip whitespace characters
if !c.is_whitespace() {
match c {
'(' => tokens.push((pos, Tok::LParen, pos+1)),
')' => tokens.push((pos, Tok::RParen, pos+1)),
'-' => tokens.push((pos, Tok::Minus, pos+1)),
'+' => tokens.push((pos, Tok::Plus, pos+1)),
'*' => tokens.push((pos, Tok::Times, pos+1)),
',' => tokens.push((pos, Tok::Comma, pos+1)),
'/' => tokens.push((pos, Tok::Div, pos+1)),
'(' => tokens.push(Tok::LParen),
')' => tokens.push(Tok::RParen),
'-' => tokens.push(Tok::Minus),
'+' => tokens.push(Tok::Plus),
'*' => tokens.push(Tok::Times),
',' => tokens.push(Tok::Comma),
'/' => tokens.push(Tok::Div),
_ if c.is_digit(10) => {
let (tmp, next) = take_while(c, &mut chars, |c| c.is_digit(10));
lookahead = next;
let end = lookahead.map(|(pos, _)| pos).unwrap_or(s.len());
tokens.push((pos, Tok::Num(i32::from_str(&tmp).unwrap()), end));
tokens.push(Tok::Num(i32::from_str(&tmp).unwrap()));
continue;
}
_ => {
@ -44,19 +43,23 @@ pub fn tokenize(s: &str) -> Vec<(usize, Tok, usize)> {
// advance to next character by default
lookahead = chars.next();
}
tokens
tokens.into_iter()
.enumerate()
.map(|(i, tok)| (i*2, tok, i*2+1))
.collect()
}
fn take_while<C,F>(c0: char, chars: &mut C, f: F) -> (String, Option<(usize, char)>)
where C: Iterator<Item=(usize, char)>, F: Fn(char) -> bool
fn take_while<C,F>(c0: char, chars: &mut C, f: F) -> (String, Option<char>)
where C: Iterator<Item=char>, F: Fn(char) -> bool
{
let mut buf = String::new();
buf.push(c0);
while let Some((pos, c)) = chars.next() {
while let Some(c) = chars.next() {
if !f(c) {
return (buf, Some((pos, c)));
return (buf, Some(c));
}
buf.push(c);

View File

@ -322,9 +322,9 @@ impl Display for SymbolKind {
SymbolKind::Name(n, ref s) =>
write!(fmt, "{}:{}", n, s),
SymbolKind::Lookahead =>
write!(fmt, "$<"),
write!(fmt, "@<"),
SymbolKind::Lookbehind =>
write!(fmt, "$>"),
write!(fmt, "@>"),
}
}
}

View File

@ -251,14 +251,15 @@ impl<'ascent,'grammar,W:Write> RecursiveAscent<'ascent,'grammar,W> {
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));",
"let {}nt = {}lookahead.as_ref().map(\
|o| ::std::clone::Clone::clone(&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);",
"let {}nt = ::std::clone::Clone::clone(&{}lookbehind);",
self.prefix, self.prefix);
}
}

View File

@ -78,9 +78,11 @@ impl MacroExpander {
SymbolKind::Repeat(repeat) =>
items.push(try!(self.expand_repeat_symbol(sym.span, *repeat))),
SymbolKind::Lookahead =>
items.push(try!(self.expand_lookahead_symbol(sym.span))),
items.push(try!(self.expand_lookaround_symbol(
sym.span, "@<", ActionKind::Lookahead))),
SymbolKind::Lookbehind =>
items.push(try!(self.expand_lookbehind_symbol(sym.span))),
items.push(try!(self.expand_lookaround_symbol(
sym.span, "@>", ActionKind::Lookbehind))),
_ =>
assert!(false, "don't know how to expand `{:?}`", sym)
}
@ -480,12 +482,21 @@ impl MacroExpander {
}
}
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 expand_lookaround_symbol(&mut self, span: Span, name: &str, action: ActionKind)
-> NormResult<GrammarItem> {
let name = NonterminalString(intern(name));
Ok(GrammarItem::Nonterminal(NonterminalData {
public: false,
span: span,
name: name,
args: vec![],
type_decl: None,
alternatives: vec![
Alternative { span: span,
expr: ExprSymbol { symbols: vec![] },
condition: None,
action: Some(action) }]
}))
}
}

View File

@ -71,3 +71,21 @@ grammar;
compare(actual, expected);
}
#[test]
fn test_lookahead() {
let grammar = parser::parse_grammar(r#"
grammar;
Expr = @<;
"#).unwrap();
let actual = expand_macros(grammar).unwrap();
let expected = parser::parse_grammar(r#"
grammar;
Expr = `@<`;
`@<` = =>@<;
"#).unwrap();
compare(actual, expected);
}

View File

@ -2,7 +2,7 @@ use super::{NormResult, NormError};
use super::norm_util::{self, AlternativeAction, Symbols};
use std::collections::{HashMap};
use grammar::parse_tree::{Alternative,
use grammar::parse_tree::{ActionKind, Alternative,
ExternToken,
Grammar, GrammarItem,
LOCATION,
@ -224,10 +224,19 @@ impl<'grammar> TypeInferencer<'grammar> {
fn alternative_type(&mut self, alt: &Alternative) -> NormResult<TypeRepr> {
match norm_util::analyze_action(alt) {
AlternativeAction::User(_) => {
AlternativeAction::User(&ActionKind::User(_)) => {
return_err!(alt.span, "cannot infer types if there is custom action code");
}
AlternativeAction::User(&ActionKind::Lookahead) |
AlternativeAction::User(&ActionKind::Lookbehind) => {
let loc_type = self.types.opt_terminal_loc_type().unwrap().clone();
Ok(TypeRepr::Nominal(NominalTypeRepr {
path: Path::option(),
types: vec![loc_type]
}))
}
AlternativeAction::Default(Symbols::Named(ref syms)) => {
return_err!(alt.span,
"cannot infer types in the presence of named symbols like `{}:{}`",

View File

@ -127,6 +127,31 @@ grammar;
])
}
#[test]
fn test_lookahead() {
compare(r#"
grammar;
extern token { type Location = usize; enum Tok { } }
A = @<;
"#, vec![
("A", "::std::option::Option<usize>"),
])
}
#[test]
fn test_spanned_macro() {
compare(r#"
grammar;
extern token { type Location = usize; enum Tok { } }
A = Spanned<"Foo">;
Spanned<T>: (Option<usize>, Option<usize>) = {
<@<> T <@>> => (<>);
};
"#, vec![
("A", "(Option<usize>, Option<usize>)"),
])
}
#[test]
fn test_action() {
compare(r#"

View File

@ -49,8 +49,6 @@ impl<W:Write> RustWrite<W> {
pub fn writeln(&mut self, out: &str) -> io::Result<()> {
let buf = out.as_bytes();
println!("indent={:?} out={:?}", self.indent, out);
// pass empty lines through with no indentation
if buf.is_empty() {
return self.write.write_all("\n".as_bytes());