mirror of
https://github.com/fluencelabs/lalrpop
synced 2025-03-16 17:00:53 +00:00
Various bits of cleanup; add some routines to compute type repr
from parse-tree given types table
This commit is contained in:
parent
9200285d49
commit
cc155debd7
@ -60,7 +60,7 @@ grammar Type<'input, T> {
|
||||
*/
|
||||
|
||||
use intern::{intern, InternedString};
|
||||
use grammar::repr::TypeRepr;
|
||||
use grammar::repr::{Types, TypeRepr};
|
||||
use std::fmt::{Display, Formatter, Error};
|
||||
use util::Sep;
|
||||
|
||||
@ -222,6 +222,20 @@ impl Symbol {
|
||||
pub fn canonical_form(&self) -> String {
|
||||
format!("{}", self)
|
||||
}
|
||||
|
||||
pub fn type_repr(&self, types: &Types) -> TypeRepr {
|
||||
match *self {
|
||||
Symbol::Terminal(_) => types.terminal_type().clone(),
|
||||
Symbol::Nonterminal(id) => types.nt_type(id).unwrap().clone(),
|
||||
Symbol::Choose(ref s) => s.type_repr(types),
|
||||
Symbol::Name(_, ref s) => s.type_repr(types),
|
||||
Symbol::Repeat(ref r) => r.op.type_repr(r.symbol.type_repr(types)),
|
||||
|
||||
Symbol::Expr(..) | Symbol::Macro(..) => {
|
||||
unreachable!("symbol {} should have been expanded away", self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Symbol {
|
||||
@ -326,3 +340,25 @@ impl RepeatOp {
|
||||
TypeRepr::Nominal { path: path, types: vec![symbol_type] }
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeRef {
|
||||
// Converts a TypeRef to a TypeRepr, assuming no inference is
|
||||
// required etc. This is safe for all types a user can directly
|
||||
// type, but not safe for the result of expanding macros.
|
||||
pub fn type_repr(&self) -> TypeRepr {
|
||||
match *self {
|
||||
TypeRef::Tuple(ref types) =>
|
||||
TypeRepr::Tuple(types.iter().map(TypeRef::type_repr).collect()),
|
||||
TypeRef::Nominal { ref path, ref types } =>
|
||||
TypeRepr::Nominal { path: path.clone(),
|
||||
types: types.iter().map(TypeRef::type_repr).collect() },
|
||||
TypeRef::Lifetime(id) =>
|
||||
TypeRepr::Lifetime(id),
|
||||
TypeRef::Id(id) =>
|
||||
TypeRepr::Nominal { path: vec![id],
|
||||
types: vec![] },
|
||||
TypeRef::OfSymbol(_) =>
|
||||
unreachable!("OfSymbol produced by parser")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,18 +26,24 @@ pub enum TypeRepr {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Types {
|
||||
terminal_type: TypeRepr,
|
||||
nonterminal_types: HashMap<InternedString, TypeRepr>
|
||||
}
|
||||
|
||||
impl Types {
|
||||
pub fn new() -> Types {
|
||||
Types { nonterminal_types: HashMap::new() }
|
||||
pub fn new(terminal_type: TypeRepr) -> Types {
|
||||
Types { terminal_type: terminal_type,
|
||||
nonterminal_types: HashMap::new() }
|
||||
}
|
||||
|
||||
pub fn add_type(&mut self, nt_id: InternedString, ty: TypeRepr) {
|
||||
assert!(self.nonterminal_types.insert(nt_id, ty).is_none());
|
||||
}
|
||||
|
||||
pub fn terminal_type(&self) -> &TypeRepr {
|
||||
&self.terminal_type
|
||||
}
|
||||
|
||||
pub fn nt_type(&self, nt_id: InternedString) -> Option<&TypeRepr> {
|
||||
self.nonterminal_types.get(&nt_id)
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ mod macro_expand;
|
||||
// Computes types where the user omitted them (or from macro
|
||||
// byproducts).
|
||||
//
|
||||
// AFTER THIS POINT: All explicit types, no `OfSymbol` types.
|
||||
// AFTER THIS POINT: there is a separate `repr::Types` table
|
||||
// providing all nonterminals with an explicit type.
|
||||
mod tyinfer;
|
||||
|
||||
// Synthesizes action code for all nonterminals.
|
||||
|
@ -16,7 +16,6 @@ pub fn infer_types(grammar: &Grammar) -> NormResult<Types> {
|
||||
}
|
||||
|
||||
struct TypeInferencer<'grammar> {
|
||||
token_type: &'grammar TypeRef,
|
||||
stack: Vec<InternedString>,
|
||||
nonterminals: HashMap<InternedString, NT<'grammar>>,
|
||||
types: Types,
|
||||
@ -29,7 +28,7 @@ struct NT<'grammar> {
|
||||
alternatives: &'grammar Vec<Alternative>,
|
||||
}
|
||||
|
||||
fn extract_token_type(grammar: &Grammar) -> NormResult<&TypeRef> {
|
||||
fn extract_token_type(grammar: &Grammar) -> NormResult<TypeRepr> {
|
||||
let mut token_types =
|
||||
grammar.items
|
||||
.iter()
|
||||
@ -50,7 +49,7 @@ fn extract_token_type(grammar: &Grammar) -> NormResult<&TypeRef> {
|
||||
return_err!(grammar.span, "multiple token types specified");
|
||||
}
|
||||
|
||||
Ok(token_type)
|
||||
Ok(token_type.type_repr())
|
||||
}
|
||||
|
||||
impl<'grammar> TypeInferencer<'grammar> {
|
||||
@ -73,10 +72,9 @@ impl<'grammar> TypeInferencer<'grammar> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(TypeInferencer { token_type: token_type,
|
||||
stack: vec![],
|
||||
Ok(TypeInferencer { stack: vec![],
|
||||
nonterminals: nonterminals,
|
||||
types: Types::new() })
|
||||
types: Types::new(token_type) })
|
||||
}
|
||||
|
||||
fn infer_types(mut self) -> NormResult<Types> {
|
||||
@ -197,7 +195,7 @@ impl<'grammar> TypeInferencer<'grammar> {
|
||||
|
||||
fn symbol_type(&mut self, symbol: &Symbol) -> NormResult<TypeRepr> {
|
||||
match *symbol {
|
||||
Symbol::Terminal(_) => self.type_ref(self.token_type),
|
||||
Symbol::Terminal(_) => Ok(self.types.terminal_type().clone()),
|
||||
Symbol::Nonterminal(id) => self.nonterminal_type(id),
|
||||
Symbol::Choose(ref s) => self.symbol_type(s),
|
||||
Symbol::Name(_, ref s) => self.symbol_type(s),
|
||||
|
@ -7,24 +7,7 @@ use grammar::repr::TypeRepr;
|
||||
|
||||
fn type_repr(s: &str) -> TypeRepr {
|
||||
let type_ref = parser::parse_type_ref(s).unwrap();
|
||||
return convert(type_ref);
|
||||
|
||||
fn convert(t: TypeRef) -> TypeRepr {
|
||||
match t {
|
||||
TypeRef::Tuple(types) =>
|
||||
TypeRepr::Tuple(types.into_iter().map(convert).collect()),
|
||||
TypeRef::Nominal { path, types } =>
|
||||
TypeRepr::Nominal { path: path,
|
||||
types: types.into_iter().map(convert).collect() },
|
||||
TypeRef::Lifetime(id) =>
|
||||
TypeRepr::Lifetime(id),
|
||||
TypeRef::Id(id) =>
|
||||
TypeRepr::Nominal { path: vec![id],
|
||||
types: vec![] },
|
||||
TypeRef::OfSymbol(_) =>
|
||||
unreachable!("OfSymbol produced by parser")
|
||||
}
|
||||
}
|
||||
return type_ref.type_repr();
|
||||
}
|
||||
|
||||
fn compare(g1: &str, expected: Vec<(&'static str, &'static str)>) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user