implement associated types for extern tokens and track an (optional)

location type
This commit is contained in:
Niko Matsakis 2015-07-15 19:38:15 -04:00
parent 59de015817
commit c92619fe15
11 changed files with 3031 additions and 2958 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,11 @@
grammar<'ast>(arena: &'ast Arena<'ast>);
use expr_arena_ast::{Arena, Node, Op};
use util::tok::Tok;
grammar<'ast>(arena: &'ast Arena<'ast>);
extern token {
type Location = u32;
enum Tok {
"(" => Tok::LParen(..),
")" => Tok::RParen(..),

File diff suppressed because it is too large Load Diff

View File

@ -24,8 +24,8 @@ mod __parse__S {
pub enum __Nonterminal<> {
E(i32),
T(i32),
S(i32),
____S(i32),
S(i32),
}
// State 0
@ -40,12 +40,12 @@ mod __parse__S {
// T = (*) "Num" ["-"]
// __S = (*) S [EOF]
//
// "Num" -> Shift(S3)
// "(" -> Shift(S2)
// "(" -> Shift(S5)
// "Num" -> Shift(S4)
//
// S -> S4
// E -> S1
// T -> S5
// T -> S2
// S -> S3
pub fn __state0<
__TOKENS: Iterator<Item=Tok>,
>(
@ -55,15 +55,15 @@ mod __parse__S {
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Num(__tok0)) => {
let mut __sym0 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state3(__lookahead, __tokens, __sym0));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __sym0 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state2(__lookahead, __tokens, __sym0));
__result = try!(__state5(__lookahead, __tokens, __sym0));
}
Some(Tok::Num(__tok0)) => {
let mut __sym0 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state4(__lookahead, __tokens, __sym0));
}
_ => {
return Err(__lookahead);
@ -72,17 +72,17 @@ mod __parse__S {
loop {
let (__lookahead, __nt) = __result;
match __nt {
__Nonterminal::S(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state4(__lookahead, __tokens, __sym0));
}
__Nonterminal::E(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state1(__lookahead, __tokens, __sym0));
}
__Nonterminal::T(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state5(__lookahead, __tokens, __sym0));
__result = try!(__state2(__lookahead, __tokens, __sym0));
}
__Nonterminal::S(__nt) => {
let __sym0 = &mut Some(__nt);
__result = try!(__state3(__lookahead, __tokens, __sym0));
}
_ => {
return Ok((__lookahead, __nt));
@ -96,8 +96,8 @@ mod __parse__S {
// E = E (*) "-" T ["-"]
// S = E (*) [EOF]
//
// "-" -> Shift(S6)
// EOF -> Reduce(S = E => ActionFn(1);)
// "-" -> Shift(S6)
//
pub fn __state1<
__TOKENS: Iterator<Item=Tok>,
@ -127,74 +127,14 @@ mod __parse__S {
}
// State 2
// E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"]
// E = (*) T [")"]
// E = (*) T ["-"]
// T = (*) "(" E ")" [")"]
// T = (*) "(" E ")" ["-"]
// T = "(" (*) E ")" [EOF]
// T = "(" (*) E ")" ["-"]
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
// E = T (*) [EOF]
// E = T (*) ["-"]
//
// "Num" -> Shift(S9)
// "(" -> Shift(S7)
// "-" -> Reduce(E = T => ActionFn(3);)
// EOF -> Reduce(E = T => ActionFn(3);)
//
// T -> S8
// E -> S10
pub fn __state2<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Num(__tok0)) => {
let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state9(__lookahead, __tokens, __sym1));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __sym1 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state7(__lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
}
}
while __sym0.is_some() {
let (__lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state8(__lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state10(__lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Ok((__lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 3
// T = "Num" (*) [EOF]
// T = "Num" (*) ["-"]
//
// EOF -> Reduce(T = "Num" => ActionFn(4);)
// "-" -> Reduce(T = "Num" => ActionFn(4);)
//
pub fn __state3<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
@ -203,15 +143,15 @@ mod __parse__S {
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
@ -219,12 +159,12 @@ mod __parse__S {
}
}
// State 4
// State 3
// __S = S (*) [EOF]
//
// EOF -> Reduce(__S = S => ActionFn(0);)
//
pub fn __state4<
pub fn __state3<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
@ -245,14 +185,14 @@ mod __parse__S {
}
}
// State 5
// E = T (*) [EOF]
// E = T (*) ["-"]
// State 4
// T = "Num" (*) [EOF]
// T = "Num" (*) ["-"]
//
// EOF -> Reduce(E = T => ActionFn(3);)
// "-" -> Reduce(E = T => ActionFn(3);)
// "-" -> Reduce(T = "Num" => ActionFn(4);)
// EOF -> Reduce(T = "Num" => ActionFn(4);)
//
pub fn __state5<
pub fn __state4<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
@ -262,15 +202,15 @@ mod __parse__S {
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
None => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
@ -278,6 +218,66 @@ mod __parse__S {
}
}
// State 5
// E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"]
// E = (*) T [")"]
// E = (*) T ["-"]
// T = (*) "(" E ")" [")"]
// T = (*) "(" E ")" ["-"]
// T = "(" (*) E ")" [EOF]
// T = "(" (*) E ")" ["-"]
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "(" -> Shift(S8)
// "Num" -> Shift(S10)
//
// T -> S7
// E -> S9
pub fn __state5<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<Tok>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __sym1 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state8(__lookahead, __tokens, __sym1));
}
Some(Tok::Num(__tok0)) => {
let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state10(__lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
}
}
while __sym0.is_some() {
let (__lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state7(__lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state9(__lookahead, __tokens, __sym0, __sym1));
}
_ => {
return Ok((__lookahead, __nt));
}
}
}
return Ok(__result);
}
// State 6
// E = E "-" (*) T [EOF]
// E = E "-" (*) T ["-"]
@ -286,8 +286,8 @@ mod __parse__S {
// T = (*) "Num" [EOF]
// T = (*) "Num" ["-"]
//
// "Num" -> Shift(S3)
// "(" -> Shift(S2)
// "Num" -> Shift(S4)
// "(" -> Shift(S5)
//
// T -> S11
pub fn __state6<
@ -304,12 +304,12 @@ mod __parse__S {
Some(Tok::Num(__tok0)) => {
let mut __sym2 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state3(__lookahead, __tokens, __sym2));
__result = try!(__state4(__lookahead, __tokens, __sym2));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state2(__lookahead, __tokens, __sym2));
__result = try!(__state5(__lookahead, __tokens, __sym2));
}
_ => {
return Err(__lookahead);
@ -331,6 +331,39 @@ mod __parse__S {
}
// State 7
// E = T (*) [")"]
// E = T (*) ["-"]
//
// ")" -> Reduce(E = T => ActionFn(3);)
// "-" -> Reduce(E = T => ActionFn(3);)
//
pub fn __state7<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 8
// E = (*) E "-" T [")"]
// E = (*) E "-" T ["-"]
// E = (*) T [")"]
@ -342,12 +375,12 @@ mod __parse__S {
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "Num" -> Shift(S9)
// "(" -> Shift(S7)
// "Num" -> Shift(S10)
// "(" -> Shift(S8)
//
// T -> S8
// E -> S12
pub fn __state7<
// T -> S7
pub fn __state8<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
@ -360,12 +393,12 @@ mod __parse__S {
Some(Tok::Num(__tok0)) => {
let mut __sym1 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state9(__lookahead, __tokens, __sym1));
__result = try!(__state10(__lookahead, __tokens, __sym1));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __sym1 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state7(__lookahead, __tokens, __sym1));
__result = try!(__state8(__lookahead, __tokens, __sym1));
}
_ => {
return Err(__lookahead);
@ -374,14 +407,14 @@ mod __parse__S {
while __sym0.is_some() {
let (__lookahead, __nt) = __result;
match __nt {
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state8(__lookahead, __tokens, __sym1));
}
__Nonterminal::E(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state12(__lookahead, __tokens, __sym0, __sym1));
}
__Nonterminal::T(__nt) => {
let __sym1 = &mut Some(__nt);
__result = try!(__state7(__lookahead, __tokens, __sym1));
}
_ => {
return Ok((__lookahead, __nt));
}
@ -390,82 +423,16 @@ mod __parse__S {
return Ok(__result);
}
// State 8
// E = T (*) [")"]
// E = T (*) ["-"]
//
// ")" -> Reduce(E = T => ActionFn(3);)
// "-" -> Reduce(E = T => ActionFn(3);)
//
pub fn __state8<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action3(__sym0);
return Ok((__lookahead, __Nonterminal::E(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 9
// T = "Num" (*) [")"]
// T = "Num" (*) ["-"]
//
// ")" -> Reduce(T = "Num" => ActionFn(4);)
// "-" -> Reduce(T = "Num" => ActionFn(4);)
//
pub fn __state9<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 10
// E = E (*) "-" T [")"]
// E = E (*) "-" T ["-"]
// T = "(" E (*) ")" [EOF]
// T = "(" E (*) ")" ["-"]
//
// ")" -> Shift(S13)
// "-" -> Shift(S14)
// ")" -> Shift(S13)
//
pub fn __state10<
pub fn __state9<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
@ -476,16 +443,16 @@ mod __parse__S {
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::RParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state13(__lookahead, __tokens, __sym0, __sym1, __sym2));
}
Some(__tok @ Tok::Minus(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state14(__lookahead, __tokens, __sym1, __sym2));
}
Some(__tok @ Tok::RParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state13(__lookahead, __tokens, __sym0, __sym1, __sym2));
}
_ => {
return Err(__lookahead);
}
@ -493,6 +460,39 @@ mod __parse__S {
return Ok(__result);
}
// State 10
// T = "Num" (*) [")"]
// T = "Num" (*) ["-"]
//
// ")" -> Reduce(T = "Num" => ActionFn(4);)
// "-" -> Reduce(T = "Num" => ActionFn(4);)
//
pub fn __state10<
__TOKENS: Iterator<Item=Tok>,
>(
mut __lookahead: Option<Tok>,
__tokens: &mut __TOKENS,
__sym0: &mut Option<i32>,
) -> Result<(Option<Tok>, __Nonterminal<>), Option<Tok>>
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __nt = super::__actions::__action4(__sym0);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
_ => {
return Err(__lookahead);
}
}
}
// State 11
// E = E "-" T (*) [EOF]
// E = E "-" T (*) ["-"]
@ -573,8 +573,8 @@ mod __parse__S {
// T = "(" E ")" (*) [EOF]
// T = "(" E ")" (*) ["-"]
//
// EOF -> Reduce(T = "(", E, ")" => ActionFn(5);)
// "-" -> Reduce(T = "(", E, ")" => ActionFn(5);)
// EOF -> Reduce(T = "(", E, ")" => ActionFn(5);)
//
pub fn __state13<
__TOKENS: Iterator<Item=Tok>,
@ -588,14 +588,14 @@ mod __parse__S {
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
None => {
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action5(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::Minus(..)) => {
None => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
@ -616,8 +616,8 @@ mod __parse__S {
// T = (*) "Num" [")"]
// T = (*) "Num" ["-"]
//
// "(" -> Shift(S7)
// "Num" -> Shift(S9)
// "Num" -> Shift(S10)
// "(" -> Shift(S8)
//
// T -> S16
pub fn __state14<
@ -631,15 +631,15 @@ mod __parse__S {
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(__tok @ Tok::LParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state7(__lookahead, __tokens, __sym2));
}
Some(Tok::Num(__tok0)) => {
let mut __sym2 = &mut Some((__tok0));
let __lookahead = __tokens.next();
__result = try!(__state9(__lookahead, __tokens, __sym2));
__result = try!(__state10(__lookahead, __tokens, __sym2));
}
Some(__tok @ Tok::LParen(..)) => {
let mut __sym2 = &mut Some(__tok);
let __lookahead = __tokens.next();
__result = try!(__state8(__lookahead, __tokens, __sym2));
}
_ => {
return Err(__lookahead);
@ -664,8 +664,8 @@ mod __parse__S {
// T = "(" E ")" (*) [")"]
// T = "(" E ")" (*) ["-"]
//
// "-" -> Reduce(T = "(", E, ")" => ActionFn(5);)
// ")" -> Reduce(T = "(", E, ")" => ActionFn(5);)
// "-" -> Reduce(T = "(", E, ")" => ActionFn(5);)
//
pub fn __state15<
__TOKENS: Iterator<Item=Tok>,
@ -679,14 +679,14 @@ mod __parse__S {
{
let mut __result: (Option<Tok>, __Nonterminal<>);
match __lookahead {
Some(Tok::Minus(..)) => {
Some(Tok::RParen(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();
let __nt = super::__actions::__action5(__sym0, __sym1, __sym2);
return Ok((__lookahead, __Nonterminal::T(__nt)));
}
Some(Tok::RParen(..)) => {
Some(Tok::Minus(..)) => {
let __sym0 = __sym0.take().unwrap();
let __sym1 = __sym1.take().unwrap();
let __sym2 = __sym2.take().unwrap();

View File

@ -33,9 +33,20 @@ pub enum GrammarItem {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ExternToken {
pub associated_types: Vec<AssociatedType>,
pub enum_token: EnumToken,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AssociatedType {
pub span: Span,
pub type_name: InternedString,
pub type_ref: TypeRef,
}
/// Recognized associated type for the token location
pub const LOCATION: &'static str = "Location";
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EnumToken {
pub type_name: TypeRef,
@ -322,6 +333,14 @@ impl Display for ExprSymbol {
}
}
impl ExternToken {
pub fn associated_type(&self, name: InternedString) -> Option<&AssociatedType> {
self.associated_types.iter()
.filter(|a| a.type_name == name)
.next()
}
}
impl ExprSymbol {
pub fn canonical_form(&self) -> String {
format!("{}", self)

View File

@ -99,14 +99,18 @@ pub struct NominalTypeRepr {
#[derive(Clone, Debug)]
pub struct Types {
terminal_enum_type: NominalTypeRepr,
terminal_loc_type: Option<TypeRepr>,
default_terminal_type: TypeRepr,
terminal_types: Map<TerminalString, TypeRepr>,
nonterminal_types: Map<NonterminalString, TypeRepr>
}
impl Types {
pub fn new(terminal_enum_type: NominalTypeRepr) -> Types {
Types { terminal_enum_type: terminal_enum_type.clone(),
pub fn new(terminal_loc_type: Option<TypeRepr>,
terminal_enum_type: NominalTypeRepr)
-> Types {
Types { terminal_loc_type: terminal_loc_type,
terminal_enum_type: terminal_enum_type.clone(),
terminal_types: map(),
default_terminal_type: TypeRepr::Nominal(terminal_enum_type),
nonterminal_types: map() }

View File

@ -3,13 +3,15 @@ use super::norm_util::{self, AlternativeAction, Symbols};
use std::collections::{HashMap};
use grammar::parse_tree::{Alternative,
EnumToken,
ExternToken,
Grammar, GrammarItem,
LOCATION,
NonterminalData, NonterminalString,
Path,
Span,
SymbolKind, TypeRef};
use grammar::repr::{NominalTypeRepr, Types, TypeRepr};
use intern::intern;
#[cfg(test)]
mod test;
@ -32,40 +34,43 @@ struct NT<'grammar> {
alternatives: &'grammar Vec<Alternative>,
}
fn extract_enum_token(grammar: &Grammar) -> NormResult<&EnumToken> {
let mut enum_tokens =
fn extract_extern_token(grammar: &Grammar) -> NormResult<&ExternToken> {
let mut extern_tokens =
grammar.items
.iter()
.filter_map(|item| {
match *item {
GrammarItem::ExternToken(ref data) => Some(&data.enum_token),
GrammarItem::ExternToken(ref data) => Some(data),
_ => None,
}
});
let enum_token = enum_tokens.next();
let enum_token = match enum_token {
let extern_token = extern_tokens.next();
let extern_token = match extern_token {
Some(tt) => tt,
None => return_err!(grammar.span, "no token type specified")
};
if let Some(_) = enum_tokens.next() {
if let Some(_) = extern_tokens.next() {
return_err!(grammar.span, "multiple token types specified");
}
Ok(enum_token)
Ok(extern_token)
}
impl<'grammar> TypeInferencer<'grammar> {
fn new(grammar: &'grammar Grammar) -> NormResult<TypeInferencer<'grammar>> {
let enum_token = try!(extract_enum_token(grammar));
let extern_token = try!(extract_extern_token(grammar));
let token_type = match enum_token.type_name.type_repr() {
let loc_type = extern_token.associated_type(intern(LOCATION))
.map(|tr| tr.type_ref.type_repr());
let enum_type = match extern_token.enum_token.type_name.type_repr() {
TypeRepr::Nominal(data) => data,
_ => panic!("enum token without nominal type passed validation")
};
let mut types = Types::new(token_type);
let mut types = Types::new(loc_type, enum_type);
// For each defined conversion, figure out the type of the
// terminal and enter it into `types` by hand if it is not the
@ -76,7 +81,7 @@ impl<'grammar> TypeInferencer<'grammar> {
// e.g. "(" => Lparen(..) ==> no custom type
// "Num" => Num(<u32>) ==> custom type is u32
// "Fraction" => Real(<u32>,<u32>) ==> custom type is (u32, u32)
for conversion in &enum_token.conversions {
for conversion in &extern_token.enum_token.conversions {
let mut tys = Vec::new();
conversion.to.for_each_binding(&mut |ty| tys.push(ty.type_repr()));
if tys.is_empty() { continue; }

View File

@ -4,9 +4,9 @@ use super::{NormResult, NormError};
use super::norm_util::{self, Symbols};
use grammar::parse_tree::*;
use intern::{read, InternedString};
use intern::{intern, read, InternedString};
use regex::Regex;
use util::{Map, Multimap, Set};
use util::{Map, Multimap, Sep, set, Set};
#[cfg(test)]
mod test;
@ -65,6 +65,24 @@ impl<'grammar> Validator<'grammar> {
match *item {
GrammarItem::Use(..) => { }
GrammarItem::ExternToken(ref data) => {
let allowed_names = vec![intern(LOCATION)];
let mut new_names = set();
for associated_type in &data.associated_types {
if !allowed_names.contains(&associated_type.type_name) {
return_err!(
associated_type.span,
"associated type `{}` not recognized, \
try one of the following: {}",
associated_type.type_name,
Sep(", ", &allowed_names));
} else if !new_names.insert(associated_type.type_name) {
return_err!(
associated_type.span,
"associated type `{}` already specified",
associated_type.type_name);
}
}
match data.enum_token.type_name {
TypeRef::Id(_) | TypeRef::Nominal { .. } => { /* OK */ }
_ => {

View File

@ -59,3 +59,10 @@ fn named_symbols() {
r#"named symbols (like `"Num"`) require a custom action"#,
r#"grammar { Term = { <n:>>>"Num"<<<>; }; }"#);
}
#[test]
fn bad_assoc_type() {
check_err(
r#"named symbols (like `"Num"`) require a custom action"#,
r#"grammar { extern token { type Foo = i32; } }"#);
}

View File

@ -18,7 +18,8 @@ rusty_peg! {
parser Parser<'input> {
// Grammar
GRAMMAR: Grammar =
(<lo:POSL> "grammar" <hi:POSR>
(<uses:{USE}>
<lo:POSL> "grammar" <hi:POSR>
<tps:[GRAMMAR_TPS]>
<parameters:[GRAMMAR_PARAMS]>
<where_clauses:[WHERE_CLAUSES]>
@ -27,7 +28,7 @@ rusty_peg! {
type_parameters: tps.unwrap_or(vec![]),
parameters: parameters.unwrap_or(vec![]),
where_clauses: where_clauses.unwrap_or(vec![]),
items: i }
items: uses.into_iter().chain(i).collect() }
};
GRAMMAR_TPS: Vec<TypeParameter> =
@ -247,11 +248,14 @@ rusty_peg! {
EXTERN_TOKEN: GrammarItem =
("extern" "token" "{"
<a0:{ASSOCIATED_TYPE}>
"enum" <lo:POSL> <t:TYPE_REF> <hi:POSR> "{"
<c0:{CONVERSION ","}> <c1:[CONVERSION]>
"}"
<a1:{ASSOCIATED_TYPE}>
"}") => {
GrammarItem::ExternToken(ExternToken {
associated_types: a0.into_iter().chain(a1).collect(),
enum_token: EnumToken {
type_name: t,
type_span: Span(lo, hi),
@ -260,6 +264,11 @@ rusty_peg! {
})
};
ASSOCIATED_TYPE: AssociatedType =
(<lo:POSL> "type" <n:ID> "=" <t:TYPE_REF> ";" <hi:POSR>) => {
AssociatedType { span: Span(lo, hi), type_name: n, type_ref: t }
};
CONVERSION: Conversion =
(<lo:POSL> <from:TERMINAL> "=>" <to:PATTERN> <hi:POSR>) => {
Conversion { span: Span(lo, hi), from: from, to: to }

View File

@ -90,6 +90,15 @@ fn token_expr() {
super::parse_grammar(r#"grammar; extern token { enum Expr { "foo" => Bar } }"#).unwrap();
}
#[test]
fn assoc_types() {
super::parse_grammar(r#"grammar;
extern token {
type Foo = u32;
enum Expr { "foo" => Bar }
type Bar = i32; }"#).unwrap();
}
#[test]
fn map1() {
super::parse_grammar(