Add some tests for repeat ops, lay groundwork for lowering

This commit is contained in:
Niko Matsakis 2015-06-17 21:33:14 -04:00
parent 13df4186ed
commit e7b377793b
6 changed files with 61 additions and 22 deletions

View File

@ -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<ActionFn>,
pub productions: Vec<Production>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TokenData {
pub token_type: TypeRepr,
pub conversions: HashMap<InternedString, InternedString>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Production {
pub nonterminal: InternedString,
pub symbols: Vec<Symbol>,
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<InternedString>,
arg_types: Vec<TypeRepr>,
ret_type: Vec<TypeRepr>,
code: String,
pub arg_names: Vec<InternedString>,
pub arg_types: Vec<TypeRepr>,
pub ret_type: Vec<TypeRepr>,
pub code: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]

View File

@ -0,0 +1,3 @@
/*!
* Lower
*/

View File

@ -445,7 +445,6 @@ impl MacroExpander {
}
}
}
}
fn maybe_tuple(v: Vec<TypeRef>) -> TypeRef {

View File

@ -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

View File

@ -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<TypeRepr> {
let symbol_type = try!(self.symbol_type(&repeat.symbol));
Ok(repeat.op.type_repr(symbol_type))
}
}
impl<'grammar> NT<'grammar> {

View File

@ -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<std::option::Option<Tok>>"),
("X", "std::vec::Vec<Tok>"),
("Y", "std::vec::Vec<Tok>"),
("Z", "std::option::Option<Tok>")
])
}