mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-03-18 18:00:50 +00:00
refactor grammar to prevent undesirable nesting of symbols and
so forth
This commit is contained in:
parent
388fbcb495
commit
6192b0b2a1
@ -174,7 +174,7 @@ pub enum Symbol {
|
||||
// ~X
|
||||
Choose(Box<Symbol>),
|
||||
|
||||
// ~x:X
|
||||
// x:X
|
||||
Name(InternedString, Box<Symbol>),
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ grammar {
|
||||
|
||||
X = {
|
||||
Y;
|
||||
~l:X "+" ~r:Y => l + r;
|
||||
l:X "+" r:Y => l + r;
|
||||
};
|
||||
|
||||
Y: i32 = "foo" => 22;
|
||||
@ -162,7 +162,7 @@ grammar {
|
||||
X = {
|
||||
Y;
|
||||
Z;
|
||||
~l:X \"+\" ~r:Y => l + r;
|
||||
l:X \"+\" r:Y => l + r;
|
||||
};
|
||||
|
||||
Y: i32 = \"foo\" => 22;
|
||||
|
@ -102,7 +102,16 @@ rusty_peg! {
|
||||
// Symbols
|
||||
|
||||
SYMBOL: Symbol =
|
||||
fold(<lhs:SYMBOL0>,
|
||||
(NAMED_SYMBOL / CHOSEN_SYMBOL / SYMBOL0);
|
||||
|
||||
NAMED_SYMBOL: Symbol =
|
||||
(<l:ID> ":" <s:SYMBOL0>) => Symbol::Name(l, Box::new(s));
|
||||
|
||||
CHOSEN_SYMBOL: Symbol =
|
||||
("~" <s:SYMBOL0>) => Symbol::Choose(Box::new(s));
|
||||
|
||||
SYMBOL0: Symbol =
|
||||
fold(<lhs:SYMBOL1>,
|
||||
(<lo:POSL> <op:REPEAT_OP> <hi:POSR>) => {
|
||||
Symbol::Repeat(Box::new(RepeatSymbol { span: Span(lo, hi),
|
||||
symbol: lhs,
|
||||
@ -114,9 +123,8 @@ rusty_peg! {
|
||||
REPEAT_OP_STAR: RepeatOp = "*" => RepeatOp::Star;
|
||||
REPEAT_OP_QUESTION: RepeatOp = "?" => RepeatOp::Question;
|
||||
|
||||
SYMBOL0: Symbol =
|
||||
(NAMED_SYMBOL / CHOSEN_SYMBOL / MACRO_SYMBOL / TERMINAL_SYMBOL /
|
||||
NT_SYMBOL / ESCAPE_SYMBOL / PAREN_SYMBOL);
|
||||
SYMBOL1: Symbol =
|
||||
(MACRO_SYMBOL / TERMINAL_SYMBOL / NT_SYMBOL / ESCAPE_SYMBOL / PAREN_SYMBOL);
|
||||
|
||||
MACRO_SYMBOL: Symbol =
|
||||
(<lo:POSL> <l:NONTERMINAL_ID> "<" <m:{MACRO_ARG_START}> <n:[SYMBOL]> ">" <hi:POSR>) => {
|
||||
@ -145,12 +153,6 @@ rusty_peg! {
|
||||
(<lo:POSL> <s:{SYMBOL}> <hi:POSR>) => ExprSymbol { span: Span(lo, hi),
|
||||
symbols: s };
|
||||
|
||||
NAMED_SYMBOL: Symbol =
|
||||
(<l:ID> ":" <s:SYMBOL>) => Symbol::Name(l, Box::new(s));
|
||||
|
||||
CHOSEN_SYMBOL: Symbol =
|
||||
("~" <s:SYMBOL>) => Symbol::Choose(Box::new(s));
|
||||
|
||||
// TypeRef
|
||||
|
||||
TYPE_REF: TypeRef =
|
||||
|
@ -1,4 +1,4 @@
|
||||
use grammar::parse_tree::TypeRef;
|
||||
use grammar::parse_tree::{Symbol, TypeRef};
|
||||
|
||||
#[test]
|
||||
fn type_ref() {
|
||||
@ -66,7 +66,7 @@ fn paren_with_plus_and_anon() {
|
||||
|
||||
#[test]
|
||||
fn named_choice() {
|
||||
super::parse_grammar(r#"grammar { Expr = ~n:Alt; }"#).unwrap();
|
||||
super::parse_grammar(r#"grammar { Expr = n:Alt; }"#).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -82,14 +82,14 @@ fn token_expr() {
|
||||
#[test]
|
||||
fn map1() {
|
||||
super::parse_grammar(
|
||||
r#"grammar { Expr = ~n:Alt+ => { { foo } }; }"#).unwrap();
|
||||
r#"grammar { Expr = n:Alt+ => { { foo } }; }"#).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(non_snake_case)]
|
||||
fn mapN() {
|
||||
super::parse_grammar(
|
||||
r#"grammar { Expr = { Bar => { Baz }; X ~n:Bar => { Y }; }; }"#).unwrap();
|
||||
r#"grammar { Expr = { Bar => { Baz }; X n:Bar => { Y }; }; }"#).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -101,10 +101,32 @@ fn macro_symbols() {
|
||||
super::parse_symbol(r#"Foo<"Baz"+, ("Balooga" Potato),>"#).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symbol_precedence() {
|
||||
// check that we parse this as choosing a X+
|
||||
let sym = super::parse_symbol(r#"~X+"#).unwrap();
|
||||
assert!(match sym {
|
||||
Symbol::Choose(..) => true,
|
||||
_ => false
|
||||
});
|
||||
|
||||
let sym = super::parse_symbol(r#"n:X+"#).unwrap();
|
||||
assert!(match sym {
|
||||
Symbol::Name(..) => true,
|
||||
_ => false
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symbol_choose_name() {
|
||||
// check that we can parse ~S and x:S but not both
|
||||
assert!(super::parse_symbol(r#"~x:X+"#).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macro_nt() {
|
||||
super::parse_nonterminal(
|
||||
r#"Comma<E>: Vec<E> = ~v:(~E ",")* ~e:E? => v.into_iter().chain(e.into_iter()).collect();"#)
|
||||
r#"Comma<E>: Vec<E> = v:(~E ",")* e:E? => v.into_iter().chain(e.into_iter()).collect();"#)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user