From bd006f8c2706522b486af5ed910eec10bc0881ad Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 24 Jul 2015 05:54:25 -0400 Subject: [PATCH] add an interesting test for an S/R conflict and patch up LALRPOP tokenizer --- lalrpop/src/lr1/test.rs | 42 +++++++++++++++++++++++++++++++++++++++++ lalrpop/src/tok/mod.rs | 2 ++ 2 files changed, 44 insertions(+) diff --git a/lalrpop/src/lr1/test.rs b/lalrpop/src/lr1/test.rs index 28799b9..37255c6 100644 --- a/lalrpop/src/lr1/test.rs +++ b/lalrpop/src/lr1/test.rs @@ -141,3 +141,45 @@ grammar; // run some random tests random_test(&grammar, &states, nt("S")); } + +#[test] +fn shift_reduce_conflict1() { + // This grammar gets a shift-reduce conflict because if the input + // is "&" (*) "L", then we see two possibilities, and we must decide + // between them: + // + // "&" (*) "L" E + // | | | + // +-------+--| + // | + // E + // + // or + // + // "&" (*) "L" + // | | + // | OPT_L E + // | | | + // +---+---+----+ + // | + // E + // + // to some extent this may be a false conflict, in that inlined + // rules would address it, but it's an interesting one for + // producing a useful error message. + + let grammar = normalized_grammar(r#" + grammar; + extern token { enum Tok { } } + E: () = { + "L"; + "&" OPT_L E; + }; + OPT_L: () = { + ; + "L"; + }; + "#); + + assert!(build_states(&grammar, nt("E")).is_err()); +} diff --git a/lalrpop/src/tok/mod.rs b/lalrpop/src/tok/mod.rs index 35e0e22..2b1ded0 100644 --- a/lalrpop/src/tok/mod.rs +++ b/lalrpop/src/tok/mod.rs @@ -26,6 +26,7 @@ pub enum Tok<'input> { If, Mut, Pub, + Type, Token, // Special keywords: these are accompanied by a series of @@ -94,6 +95,7 @@ const KEYWORDS: &'static [(&'static str, Tok<'static>)] = &[ ("mut", Mut), ("pub", Pub), ("token", Token), + ("type", Type), ]; impl<'input> Tokenizer<'input> {