From e7b377793b82ade08664bd0dcadb7ab01412edad Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 17 Jun 2015 21:33:14 -0400 Subject: [PATCH] Add some tests for repeat ops, lay groundwork for lowering --- src/grammar/repr.rs | 34 +++++++++++++++++++++++++++---- src/normalize/lower/mod.rs | 3 +++ src/normalize/macro_expand/mod.rs | 1 - src/normalize/mod.rs | 7 ++----- src/normalize/tyinfer/mod.rs | 20 ++++++++---------- src/normalize/tyinfer/test.rs | 18 ++++++++++++++++ 6 files changed, 61 insertions(+), 22 deletions(-) create mode 100644 src/normalize/lower/mod.rs diff --git a/src/grammar/repr.rs b/src/grammar/repr.rs index 633a08d..51e4a8a 100644 --- a/src/grammar/repr.rs +++ b/src/grammar/repr.rs @@ -9,12 +9,38 @@ use std::collections::HashMap; use std::fmt::{Display, Formatter, Error}; use util::Sep; +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Grammar { + pub token: TokenData, + pub action_fns: Vec, + pub productions: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TokenData { + pub token_type: TypeRepr, + pub conversions: HashMap, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Production { + pub nonterminal: InternedString, + pub symbols: Vec, + pub action_fn: ActionFnIndex, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Symbol { + Nonterminal(InternedString), + Terminal(InternedString), +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct ActionFn { - arg_names: Vec, - arg_types: Vec, - ret_type: Vec, - code: String, + pub arg_names: Vec, + pub arg_types: Vec, + pub ret_type: Vec, + pub code: String, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/src/normalize/lower/mod.rs b/src/normalize/lower/mod.rs new file mode 100644 index 0000000..833b167 --- /dev/null +++ b/src/normalize/lower/mod.rs @@ -0,0 +1,3 @@ +/*! + * Lower + */ diff --git a/src/normalize/macro_expand/mod.rs b/src/normalize/macro_expand/mod.rs index 7f821a5..8248e86 100644 --- a/src/normalize/macro_expand/mod.rs +++ b/src/normalize/macro_expand/mod.rs @@ -445,7 +445,6 @@ impl MacroExpander { } } } - } fn maybe_tuple(v: Vec) -> TypeRef { diff --git a/src/normalize/mod.rs b/src/normalize/mod.rs index 36ad42c..727d922 100644 --- a/src/normalize/mod.rs +++ b/src/normalize/mod.rs @@ -47,11 +47,8 @@ mod macro_expand; // providing all nonterminals with an explicit type. mod tyinfer; -// Synthesizes action code for all nonterminals. -// -// AFTER THIS POINT: All nonterminals have action code, and all -// Symbol::Choose and Symbol::Name are removed. -// mod action; +// Lowers the parse tree to the repr notation. +mod lower; /////////////////////////////////////////////////////////////////////////// // Shared routines diff --git a/src/normalize/tyinfer/mod.rs b/src/normalize/tyinfer/mod.rs index 9ac0d22..fa1c25e 100644 --- a/src/normalize/tyinfer/mod.rs +++ b/src/normalize/tyinfer/mod.rs @@ -4,7 +4,7 @@ use super::norm_util::{self, AlternativeAction, Symbols}; use std::collections::{HashMap}; use intern::{InternedString}; use grammar::parse_tree::{Alternative, Grammar, GrammarItem, - NonterminalData, RepeatSymbol, Span, Symbol, TypeRef}; + NonterminalData, Span, Symbol, TypeRef}; use grammar::repr::{Types, TypeRepr}; #[cfg(test)] @@ -119,12 +119,14 @@ impl<'grammar> TypeInferencer<'grammar> { id); } - for (ty, alt) in alternative_types[1..].iter().zip(&nt.alternatives[1..]) { + for ((ty, alt), i) in + alternative_types[1..].iter().zip(&nt.alternatives[1..]).zip(1..) + { if &alternative_types[0] != ty { return_err!(alt.expr.span, - "type of this alternative is `{}`, \ + "type of alternative #{} is `{}`, \ but type of first alternative is `{}`", - ty, alternative_types[0]); + i+1, ty, alternative_types[0]); } } @@ -199,18 +201,12 @@ impl<'grammar> TypeInferencer<'grammar> { Symbol::Nonterminal(id) => self.nonterminal_type(id), Symbol::Choose(ref s) => self.symbol_type(s), Symbol::Name(_, ref s) => self.symbol_type(s), - Symbol::Repeat(ref rep) => self.repeat_type(rep), - Symbol::Expr(..) | Symbol::Macro(..) => { - unreachable!("symbol {} should have been expanded away", symbol) + Symbol::Repeat(..) | Symbol::Expr(..) | Symbol::Macro(..) => { + unreachable!("symbol `{:?}` should have been expanded away", symbol) } } } - - fn repeat_type(&mut self, repeat: &RepeatSymbol) -> NormResult { - let symbol_type = try!(self.symbol_type(&repeat.symbol)); - Ok(repeat.op.type_repr(symbol_type)) - } } impl<'grammar> NT<'grammar> { diff --git a/src/normalize/tyinfer/test.rs b/src/normalize/tyinfer/test.rs index 619b160..d2d8d62 100644 --- a/src/normalize/tyinfer/test.rs +++ b/src/normalize/tyinfer/test.rs @@ -114,3 +114,21 @@ grammar Foo { ("Y", "Tok") ]) } + +#[test] +fn test_star_plus_question() { + compare(" +grammar Foo { + token Tok where { }; + A = Z*; + X = \"Hi\"*; + Y = \"Hi\"+; + Z = \"Hi\"?; +} +", vec![ + ("A", "std::vec::Vec>"), + ("X", "std::vec::Vec"), + ("Y", "std::vec::Vec"), + ("Z", "std::option::Option") + ]) +}