mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-04-14 13:56:07 +00:00
Add some tests for repeat ops, lay groundwork for lowering
This commit is contained in:
parent
13df4186ed
commit
e7b377793b
@ -9,12 +9,38 @@ use std::collections::HashMap;
|
|||||||
use std::fmt::{Display, Formatter, Error};
|
use std::fmt::{Display, Formatter, Error};
|
||||||
use util::Sep;
|
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)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct ActionFn {
|
pub struct ActionFn {
|
||||||
arg_names: Vec<InternedString>,
|
pub arg_names: Vec<InternedString>,
|
||||||
arg_types: Vec<TypeRepr>,
|
pub arg_types: Vec<TypeRepr>,
|
||||||
ret_type: Vec<TypeRepr>,
|
pub ret_type: Vec<TypeRepr>,
|
||||||
code: String,
|
pub code: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
3
src/normalize/lower/mod.rs
Normal file
3
src/normalize/lower/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/*!
|
||||||
|
* Lower
|
||||||
|
*/
|
@ -445,7 +445,6 @@ impl MacroExpander {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_tuple(v: Vec<TypeRef>) -> TypeRef {
|
fn maybe_tuple(v: Vec<TypeRef>) -> TypeRef {
|
||||||
|
@ -47,11 +47,8 @@ mod macro_expand;
|
|||||||
// providing all nonterminals with an explicit type.
|
// providing all nonterminals with an explicit type.
|
||||||
mod tyinfer;
|
mod tyinfer;
|
||||||
|
|
||||||
// Synthesizes action code for all nonterminals.
|
// Lowers the parse tree to the repr notation.
|
||||||
//
|
mod lower;
|
||||||
// AFTER THIS POINT: All nonterminals have action code, and all
|
|
||||||
// Symbol::Choose and Symbol::Name are removed.
|
|
||||||
// mod action;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Shared routines
|
// Shared routines
|
||||||
|
@ -4,7 +4,7 @@ use super::norm_util::{self, AlternativeAction, Symbols};
|
|||||||
use std::collections::{HashMap};
|
use std::collections::{HashMap};
|
||||||
use intern::{InternedString};
|
use intern::{InternedString};
|
||||||
use grammar::parse_tree::{Alternative, Grammar, GrammarItem,
|
use grammar::parse_tree::{Alternative, Grammar, GrammarItem,
|
||||||
NonterminalData, RepeatSymbol, Span, Symbol, TypeRef};
|
NonterminalData, Span, Symbol, TypeRef};
|
||||||
use grammar::repr::{Types, TypeRepr};
|
use grammar::repr::{Types, TypeRepr};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -119,12 +119,14 @@ impl<'grammar> TypeInferencer<'grammar> {
|
|||||||
id);
|
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 {
|
if &alternative_types[0] != ty {
|
||||||
return_err!(alt.expr.span,
|
return_err!(alt.expr.span,
|
||||||
"type of this alternative is `{}`, \
|
"type of alternative #{} is `{}`, \
|
||||||
but type of first 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::Nonterminal(id) => self.nonterminal_type(id),
|
||||||
Symbol::Choose(ref s) => self.symbol_type(s),
|
Symbol::Choose(ref s) => self.symbol_type(s),
|
||||||
Symbol::Name(_, 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(..) => {
|
Symbol::Repeat(..) | Symbol::Expr(..) | Symbol::Macro(..) => {
|
||||||
unreachable!("symbol {} should have been expanded away", symbol)
|
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> {
|
impl<'grammar> NT<'grammar> {
|
||||||
|
@ -114,3 +114,21 @@ grammar Foo {
|
|||||||
("Y", "Tok")
|
("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>")
|
||||||
|
])
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user