// /*
// See
// https://github.com/rust-lang/rust/blob/master/src/grammar/lexer.l
// https://github.com/rust-lang/rust/blob/master/src/grammar/parser-lalr.y
// https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs
// */
extern crate grammar;
use std::cmp::Ordering;
use grammar::{Associativity,EarleyKind,State,Parser,ParsingTablesTrait,AmbiguityInfo};
use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::rc::Rc;
use std::collections::HashMap;
use std::fmt::{self,Display,Formatter};
#[derive(Clone,Debug,PartialEq)]
enum PatKind
{
Fixme,
Underscore,
Ref(Rc<PatKind>),
RefMut(Rc<PatKind>),
Void,
Tuple(Vec<PatKind>),
Path(PathKind),
EnumEmpty(Rc<Token>),
Enum(Rc<Token>,Vec<PatKind>),//name,tuple
BindedIdent(BindKind,String)
}
#[derive(Clone,Debug,PartialEq)]
enum TyKind
{
Fixme,
Underscore,
Ref(Rc<TyKind>),
RefMut(Rc<TyKind>),
RefLifetime(String,bool,Rc<TyKind>),//lifetime,mut,type
Void,
Path(PathWKind),
Tuple(Vec<TyLf>)
}
#[derive(Clone,Debug,PartialEq)]
enum ExprKind
{
Fixme,
Single(Rc<Token>),
Member(Rc<ExprKind>,PathKind),//object, attribute_or_method
Index(Rc<ExprKind>,Option<Rc<ExprKind>>),//object, index
Call(Rc<ExprKind>,Vec<ExprKind>),//function,arguments
Parentheses(Vec<ExprKind>),
Infix(Rc<ExprKind>,Rc<Token>,Rc<ExprKind>),//left,symbol,right
Ref(Rc<ExprKind>),
RefMut(Rc<ExprKind>),
Prefix(Rc<Token>,Rc<ExprKind>),//symbol,operand
Lambda(Vec<(PatKind,Option<TyLf>)>,Option<TyKind>,Rc<ExprKind>),//params,optional return,expression
Struct(PathKind,Vec<(String,Option<ExprKind>)>),//path to struct name, initializations
Range(Option<Rc<ExprKind>>,Option<Rc<ExprKind>>),
Return(Option<Rc<ExprKind>>),
Break(Option<String>)//optional lifetime or ident
}
#[derive(Clone,Debug,PartialEq)]
enum StmtKind
{
Let(PatKind,Option<TyLf>,Option<ExprKind>),
Item(Vec<AttrKind>,ItemKind),//attributes, item
Block(Vec<AttrKind>,Rc<Token>),//attributes, block
Expr(Vec<AttrKind>,ExprKind),//attributes, expression
Empty
}
#[derive(Clone,Debug,PartialEq)]
enum AttrKind
{
Documentation(String),
Flag(String),
Value(String,Rc<Token>),
Sequence(String,Vec<AttrKind>)
}
//With colons
#[derive(Clone,Debug,PartialEq)]
enum PathKind
{
Fixme,
Ident(String),
Super,
Absolute(Rc<PathKind>),
FromSelf(Rc<PathKind>),
StepIdent(Rc<PathKind>,String),
StepSuper(Rc<PathKind>),
GenericArgs(Rc<PathKind>,Vec<TyLf>),
Literal(Rc<Token>)
}
//Without colons
#[derive(Clone,Debug,PartialEq)]
enum PathWKind
{
Fixme,
Ident(String),
IdentGeneric(String,Vec<TyLf>),
Function(String,Vec<TyLf>,Rc<Token>),
StepIdent(Rc<PathWKind>,String),
StepIdentGeneric(Rc<PathWKind>,String,Vec<TyLf>),
StepFunction(Rc<PathWKind>,String,Vec<TyLf>,Rc<Token>)
}
//No types
#[derive(Clone,Debug,PartialEq)]
enum PathNKind
{
Fixme,
Ident(String),
AbsoluteIdent(String),
FromSelf,
AbsoluteSelf,
Super,
AbsoluteSuper,
Step(Rc<PathNKind>,String)
}
#[derive(Clone,Debug,PartialEq)]
enum ViewKind
{
Fixme,
Path(PathNKind,Option<String>),
All(Option<PathNKind>),
Selection(Option<PathNKind>,Vec<String>),
ExternCrate(String,Option<String>)//crate id, as name
}
#[derive(Clone,Debug,PartialEq)]
enum BindKind
{
Ref,
RefMut,
Mut
}
#[derive(Clone,Debug,PartialEq)]
enum ItemKind
{
Fixme,
Macro(Rc<Token>,Option<Rc<Token>>,Rc<Token>),
FN(String, Vec<String>,Vec<String>,Vec<(PatKind,TyLf)>,Option<TyKind>,Vec<StmtKind>,Option<ExprKind>),//name, lifetimes, generic params, params(pattern,type), return type, block statements, block expression
Method(String, Vec<String>,Vec<String>,bool,bool,bool,Option<TyLf>,Vec<(PatKind,TyLf)>,Option<TyKind>,Vec<StmtKind>,Option<ExprKind>),//name, lifetimes, generic params, has_self, has_ref, has_mut, self_type, params(pattern,type), return type, block statements, block expression
Terminal(String,Option<Rc<Token>>,Vec<ItemKind>),
Nonterminal(String,Option<Rc<Token>>,Vec<Rc<Token>>),
View(ViewKind),
Enum(String,Vec<String>,Vec<String>,Vec<(String,Vec<TyLf>)>),//name, lifetimes, params, defs
Impl(Vec<String>,Vec<String>,Option<PathWKind>,TyLf,Vec<ItemKind>),//lifetimes, generic params, optional path of trait, type of the thing being implemented, subitems
Struct(String,Vec<String>,Vec<String>,Vec<(String,TyLf)>)//name, lifetimes, generic params, fields
}
#[derive(Clone,Debug,PartialEq)]
enum TyLf
{
Type(TyKind),
Lifetime(String)
}
impl Display for PatKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&PatKind::Fixme => write!(f," FIXME "),
&PatKind::Underscore => write!(f,"_"),
&PatKind::Ref(ref kind) => write!(f,"& {}",kind),
&PatKind::RefMut(ref kind) => write!(f,"&mut {}",kind),
&PatKind::Void => write!(f,"()"),
&PatKind::Tuple(ref tuple) => write!(f,"({})",tuple.iter().map(|p|p.to_string()).collect::<Vec<String>>().join(",")),
&PatKind::Path(ref token) => write!(f,"{}",token),
&PatKind::EnumEmpty(ref name) => write!(f,"{}",name),
&PatKind::Enum(ref name, ref tuple) => write!(f,"{}({})",name,tuple.iter().map(|p|p.to_string()).collect::<Vec<String>>().join(",")),
&PatKind::BindedIdent(BindKind::Ref, ref string) => write!(f,"ref {}",string),
&PatKind::BindedIdent(BindKind::RefMut, ref string) => write!(f,"ref mut {}",string),
&PatKind::BindedIdent(BindKind::Mut, ref string) => write!(f,"mut {}",string),
}
}
}
impl Display for TyKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&TyKind::Fixme => write!(f," FIXME "),
&TyKind::Underscore => write!(f,"_"),
&TyKind::Ref(ref kind) => write!(f,"& {}",kind),
&TyKind::RefMut(ref kind) => write!(f,"&mut {}",kind),
&TyKind::RefLifetime(ref lifetime, true ,ref kind) => write!(f,"&{} mut {}",lifetime,kind),
&TyKind::RefLifetime(ref lifetime, false ,ref kind) => write!(f,"&{} {}",lifetime,kind),
&TyKind::Void => write!(f,"()"),
&TyKind::Path(ref path) => write!(f,"{}",path),
&TyKind::Tuple(ref list) => write!(f,"({})",list.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(",")),
}
}
}
impl Display for ExprKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&ExprKind::Fixme => write!(f," FIXME "),
&ExprKind::Single(ref token) => write!(f,"{}",token),
&ExprKind::Member(ref kind, ref path) => write!(f,"{}.{}",kind,path),
&ExprKind::Index(ref object, None) => write!(f,"{}[]",object),
&ExprKind::Index(ref object, Some(ref index)) => write!(f,"{}[{}]",object,index),
&ExprKind::Call(ref function, ref arguments) => write!(f,"{}({})",function,arguments.iter().map(|x| x.to_string() ).collect::<Vec<String>>().join(",")),
&ExprKind::Parentheses(ref list) => write!(f,"({})",list.iter().map(|x| x.to_string() ).collect::<Vec<String>>().join(",")),
&ExprKind::Infix(ref left,ref symbol,ref right) => write!(f,"{} {} {}",left,symbol,right),
&ExprKind::Ref(ref expr) => write!(f,"&{}",expr),
&ExprKind::RefMut(ref expr) => write!(f,"&mut {}",expr),
&ExprKind::Prefix(ref symbol, ref expr) => write!(f,"{} {}",symbol,expr),
&ExprKind::Lambda(ref args, ref ot, ref expr) => write!(f,"|{}|{}{}",args.iter().map(|&(ref pat,ref opt)|match opt{
&None => pat.to_string(),
&Some(ref t) => format!("{}:{}",pat,t),
}).collect::<Vec<String>>().join(","),match ot { &None=>String::from(""), &Some(ref t)=>t.to_string(), },expr),
&ExprKind::Struct(ref path, ref initializations) => write!(f,"{}{{{}}}",path,initializations.iter().map(|&(ref s,ref oe)|match oe{
&None => format!("{},",s),
&Some(ref e) => format!("{}:{},",s,e),
}).collect::<Vec<String>>().join("\n")),
&ExprKind::Range(Some(ref left),None) => write!(f,"{}..",left),
&ExprKind::Range(Some(ref left),Some(ref right)) => write!(f,"{}..{}",left,right),
&ExprKind::Range(None,Some(ref right)) => write!(f,"..{}",right),
&ExprKind::Range(None,None) => write!(f,".."),
&ExprKind::Return(None) => write!(f,"return"),
&ExprKind::Return(Some(ref expr)) => write!(f,"return {}",expr),
&ExprKind::Break(None) => write!(f,"break"),
&ExprKind::Break(Some(ref string)) => write!(f,"break {}",string),
}
}
}
impl Display for StmtKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&StmtKind::Let(ref pattern,ref option_type,ref option_expr) =>
{
write!(f,"let {}",pattern).unwrap();
if let &Some(ref t)=option_type
{
write!(f,":{}",t).unwrap();
}
if let &Some(ref e)=option_expr
{
write!(f,"={}",e).unwrap();
}
write!(f,";")
},
&StmtKind::Item(ref attrs, ref token) => write!(f,"{}",token),
&StmtKind::Block(ref attrs, ref token) => write!(f,"{}",token),
&StmtKind::Expr(ref attrs, ref token) => write!(f,"{};",token),
&StmtKind::Empty => write!(f,";"),
}
}
}
impl AttrKind
{
fn simple_to_string(&self)->String
{
match self
{
&AttrKind::Documentation(ref string) => string.clone(),
&AttrKind::Flag(ref string) => string.clone(),
&AttrKind::Value(ref string,ref token) => format!("{}={}",string,token),
&AttrKind::Sequence(ref string, ref attributes) => format!("{}({})",string,attributes.iter().map(|x|x.simple_to_string()).collect::<Vec<String>>().join(",")),
}
}
}
impl Display for AttrKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&AttrKind::Documentation(ref string) => write!(f,"{}",string),
&AttrKind::Flag(ref string) => write!(f,"#[{}]",string),
&AttrKind::Value(ref string,ref token) => write!(f,"#[{}={}]",string,token),
&AttrKind::Sequence(ref string, ref attributes) => write!(f,"#[{}({})]",string,attributes.iter().map(|x|x.simple_to_string()).collect::<Vec<String>>().join(",")),
}
}
}
impl Display for PathKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&PathKind::Fixme => write!(f,"::fixme::"),
&PathKind::Ident(ref string) => write!(f,"{}",string),
&PathKind::Super => write!(f,"super"),
&PathKind::Absolute(ref path) => write!(f,"::{}",path),
&PathKind::FromSelf(ref path) => write!(f,"self::{}",path),
&PathKind::StepIdent(ref path, ref string) => write!(f,"{}::{}",path,string),
&PathKind::StepSuper(ref path) => write!(f,"{}::super",path),
&PathKind::GenericArgs(ref path, ref ga) => write!(f,"{}::<{}>",path,ga.iter().map(|x|x.to_string()).collect::<Vec<String>>().join(",")),
&PathKind::Literal(ref token) => write!(f,"{}",token),
}
}
}
impl Display for PathWKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&PathWKind::Fixme => write!(f,"::fixme::"),
&PathWKind::Ident(ref string) => write!(f,"{}",string),
&PathWKind::IdentGeneric(ref string,ref gens) => write!(f,"{}<{}>",string,gens.iter().map(|g|g.to_string()).collect::<Vec<String>>().join(",")),
&PathWKind::Function(ref string,ref arguments,ref t_return_type) => write!(f,"{}({}){}",string,arguments.iter().map(|x|x.to_string()).collect::<Vec<String>>().join(","),t_return_type),
&PathWKind::StepIdent(ref path, ref string) => write!(f,"{}::{}",path,string),
&PathWKind::StepIdentGeneric(ref path, ref string, ref gens) => write!(f,"{}::{}<{}>",path,string,gens.iter().map(|g|g.to_string()).collect::<Vec<String>>().join(",")),
&PathWKind::StepFunction(ref path,ref string,ref arguments,ref t_return_type) => write!(f,"{}::{}({}){}",path,string,arguments.iter().map(|x|x.to_string()).collect::<Vec<String>>().join(","),t_return_type),
}
}
}
impl Display for PathNKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&PathNKind::Fixme => write!(f,"::fixme::"),
&PathNKind::Ident(ref string) => write!(f,"{}",string),
&PathNKind::AbsoluteIdent(ref string) => write!(f,"::{}",string),
&PathNKind::FromSelf => write!(f,"self"),
&PathNKind::AbsoluteSelf => write!(f,"::self"),
&PathNKind::Super => write!(f,"super"),
&PathNKind::AbsoluteSuper => write!(f,"::super"),
&PathNKind::Step(ref path,ref string) => write!(f,"{}::{}",path,string),
}
}
}
impl Display for ViewKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&ViewKind::Fixme => write!(f,"view fixme;"),
&ViewKind::Path(ref path,None) => write!(f,"use {};",path),
&ViewKind::Path(ref path,Some(ref string)) => write!(f,"use {} as {};",path,string),
&ViewKind::All(None) => write!(f,"use *;"),
&ViewKind::All(Some(ref path)) => write!(f,"use {}::*;",path),
&ViewKind::Selection(None,ref list) => write!(f,"use {{{}}};",list.join(",")),
&ViewKind::Selection(Some(ref path),ref list) => write!(f,"use {}::{{{}}};",path,list.join(",")),
&ViewKind::ExternCrate(ref name, None) => write!(f,"extern crate {};",name),
&ViewKind::ExternCrate(ref name, Some(ref string_as)) => write!(f,"extern crate {} as {};",name,string_as),
}
}
}
impl Display for ItemKind
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&ItemKind::Fixme => write!(f,"fixme {{ }}"),
&ItemKind::Macro(ref name, ref subname, ref token) => write!(f,"{}!{};",name,token),//FIXME
&ItemKind::FN(ref name, ref lifetimes, ref gp, ref params, ref oret, ref block_stmts, ref block_expr) =>
{
//write!(f,"fn fixme() {{ }}"),
write!(f,"fn {}",name).unwrap();
if (lifetimes.len()>0) || ((gp.len())>0)
{
//write!(f,"<{}>",gp.join(",")).unwrap();
write!(f,"<{}>",lifetimes.iter().chain(gp.iter()).map(|x|x.clone()).collect::<Vec<String>>().join(",")).unwrap();
}
write!(f,"({})",params.iter().map(|&(ref p,ref t)| format!("{}:{}",p,t) ).collect::<Vec<String>>().join(",")).unwrap();
if let &Some(ref ret)=oret
{
write!(f,"->{}",ret).unwrap();
}
writeln!(f,"{{").unwrap();
for stmt in block_stmts
{
writeln!(f,"{}",stmt).unwrap();
}
if let &Some(ref e)=block_expr
{
write!(f,"{}",e).unwrap();
}
writeln!(f,"}}")
},
&ItemKind::Method(ref name, ref lifetimes, ref gp, has_self, q_self_has_ref, q_self_has_mut, ref o_self_type, ref params, ref oret, ref block_stmts, ref block_expr) =>
{
//write!(f,"fn fixme() {{ }}"),
write!(f,"fn {}",name).unwrap();
if (lifetimes.len()>0) || (gp.len()>0)
{
//write!(f,"<{}>",gp.join(",")).unwrap();
write!(f,"<{}>",lifetimes.iter().chain(gp.iter()).map(|x|x.clone()).collect::<Vec<String>>().join(",")).unwrap();
}
write!(f,"(").unwrap();
if has_self
{
if q_self_has_ref
{
write!(f,"&").unwrap();
}
if q_self_has_mut
{
write!(f,"mut ").unwrap();
}
write!(f,"self").unwrap();
if let &Some(ref t)=o_self_type
{
write!(f,":{}",t).unwrap();
}
if params.len()>0
{
write!(f,",").unwrap();
}
}
write!(f,"{})",params.iter().map(|&(ref p,ref t)| format!("{}:{}",p,t) ).collect::<Vec<String>>().join(",")).unwrap();
if let &Some(ref ret)=oret
{
write!(f,"->{}",ret).unwrap();
}
writeln!(f,"{{").unwrap();
for stmt in block_stmts
{
writeln!(f,"{}",stmt).unwrap();
}
if let &Some(ref e)=block_expr
{
write!(f,"{}",e).unwrap();
}
writeln!(f,"}}")
},
&ItemKind::Terminal(_,_,_) => panic!("Should not be printing this"),
&ItemKind::Nonterminal(_,_,_) => panic!("Should not be printing this"),
&ItemKind::View(ref view) => write!(f,"{}",view),
&ItemKind::Enum(ref id, ref lifetimes, ref params, ref defs) =>
{
write!(f,"enum {}",id).unwrap();
if (lifetimes.len()>0) || (params.len()>0)
{
//write!(f,"({})",params.join(",")).unwrap();
write!(f,"<{}>",lifetimes.iter().chain(params.iter()).map(|x|x.clone()).collect::<Vec<String>>().join(",")).unwrap();
}
writeln!(f,"{{").unwrap();
for &(ref name,ref tys) in defs
{
write!(f,"{}",name).unwrap();
if tys.len()>0
{
write!(f,"({})",tys.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(",")).unwrap();
}
writeln!(f,",").unwrap();
}
writeln!(f,"}}")
},
&ItemKind::Impl(ref lifetimes, ref gp, ref otrait, ref t, ref items) =>
{
write!(f,"impl").unwrap();
if (lifetimes.len()>0) || (gp.len()>0)
{
//write!(f,"<{}>",gp.join(",")).unwrap();
write!(f,"<{}>",lifetimes.iter().chain(gp.iter()).map(|x|x.clone()).collect::<Vec<String>>().join(",")).unwrap();
}
if let &Some(ref tr)=otrait
{
writeln!(f," {} for {} {{",tr,t).unwrap();
}
else
{
writeln!(f," {} {{",t).unwrap();
}
for item in items
{
writeln!(f,"{}",item).unwrap();
}
writeln!(f,"}}")
},
&ItemKind::Struct(ref name, ref lifetimes, ref gp, ref fields) =>
{
write!(f,"struct {}",name).unwrap();
if (lifetimes.len()>0) || (gp.len()>0)
{
//write!(f,"<{}>",gp.join(",")).unwrap();
write!(f,"<{}>",lifetimes.iter().chain(gp.iter()).map(|x|x.clone()).collect::<Vec<String>>().join(",")).unwrap();
}
writeln!(f,"{{").unwrap();
for &(ref name,ref ty) in fields
{
writeln!(f,"{}:{},",name,ty).unwrap();
}
writeln!(f,"}}")
},
}
}
}
impl Display for TyLf
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&TyLf::Type(ref t) => write!(f,"{}",t),
&TyLf::Lifetime(ref string) => write!(f,"{}",string),
}
}
}
impl Display for Token
{
fn fmt(&self, f:&mut Formatter) -> fmt::Result
{
match self
{
&Token::TySum(ref kind) => write!(f,"{}",kind),
&Token::Pat(ref kind) => write!(f,"{}",kind),
&Token::LitOrPath(ref string) => write!(f,"{}",string),
&Token::NonblockExpr(ref expr) => write!(f,"{}",expr),
&Token::PathExpr(ref string) => write!(f,"{}",string),
&Token::Block(ref stmts, None) => write!(f,"{{{}}}", stmts.iter().map(|s| s.to_string() ).collect::<Vec<String>>().join("\n") ),
&Token::Block(ref stmts, Some(ref expr)) => write!(f,"{{{} {}}}", stmts.iter().map(|s| s.to_string() ).collect::<Vec<String>>().join("\n") , expr),
&Token::Equal => write!(f,"="),
&Token::Lit(ref token) => write!(f,"{}",token),
&Token::LitInteger(x) => write!(f,"{}",x),
&Token::LitStr(ref string) => write!(f,"{}",string),
&Token::LitChar(c) => match c
{
'\'' => write!(f,"'\\\''"),
'\\' => write!(f,"'\\\\'"),
_ => write!(f,"'{}'",c),
},
&Token::Str(ref string) => write!(f,"{}",string),
&Token::BlockExpr(ref token) => write!(f,"{}",token),
&Token::ExprMatch(ref expr,ref clauses) => write!(f,"match {} {{ {} }}",expr,clauses.iter().map(|c|c.to_string()).collect::<Vec<String>>().join(" ")),
&Token::ExprIf(ref expr, ref block, None) => write!(f,"if {} {}",expr,block),
&Token::ExprIf(ref expr, ref block, Some(ref q_else_block)) => write!(f,"if {} {} else {}",expr,block,q_else_block),
&Token::ExprIfLet(ref pattern, ref expr, ref block, None) => write!(f,"if let {}={} {}",pattern,expr,block),
&Token::ExprIfLet(ref pattern, ref expr, ref block, Some(ref q_else_block)) => write!(f,"if let {}={} {} else {}",pattern,expr,block,q_else_block),
&Token::ExprFor(ref pattern, ref expr, ref block) => write!(f,"for {} in {} {}",pattern,expr,block),
&Token::ExprWhile(ref expr, ref block) => write!(f,"while {} {}",expr,block),
&Token::True => write!(f,"true"),
&Token::False => write!(f,"false"),
&Token::Ref => write!(f,"ref"),
&Token::For => write!(f,"for"),
&Token::Match => write!(f,"match"),
&Token::If => write!(f,"if"),
&Token::Else => write!(f,"else"),
&Token::MacroExpr(ref token,None,ref trees) => write!(f,"{}!{}",token,trees),
&Token::DelimitedTokenTrees(ref trees) => write!(f,"{}",trees),
&Token::BracketsDelimitedTokenTrees(ref trees) => write!(f,"[{}]",trees.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(" ")),
&Token::ParensDelimitedTokenTrees(ref trees) => write!(f,"({})",trees.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(" ")),
&Token::BracesDelimitedTokenTrees(ref trees) => write!(f,"{{{}}}",trees.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(" ")),
&Token::LiteralIdent(ref string) => write!(f,"{}",string),
&Token::Dot => write!(f,"."),
&Token::Comma => write!(f,","),
&Token::ModSep => write!(f,"::"),
&Token::Vertical => write!(f,"|"),
&Token::Ampersand => write!(f,"&"),
&Token::Plus => write!(f,"+"),
&Token::Minus => write!(f,"-"),
&Token::Star => write!(f,"*"),
&Token::Bang => write!(f,"!"),
&Token::LT => write!(f,"<"),
&Token::GT => write!(f,">"),
&Token::NE => write!(f,"!="),
&Token::EqualEqual => write!(f,"=="),
&Token::AndAnd => write!(f,"&&"),
&Token::OrOr => write!(f,"||"),
&Token::PlusEqual => write!(f,"+="),
&Token::FatArrow => write!(f,"=>"),
&Token::DotDot => write!(f,".."),
&Token::MatchClause(ref attributes,ref pattern, ref token) => write!(f,"{} => {},",pattern,token),//FIXME
&Token::PatTup(ref patterns) => write!(f,"{}",patterns.iter().map(|p|p.to_string()).collect::<Vec<String>>().join(" ")),
&Token::LittleSelf => write!(f,"self"),
_ => panic!("panic displaying {:?}",self),
//_ => Err(fmt::Error),
}
}
}
re_terminal!(Static,"static");
re_terminal!(Mut,"mut");
re_terminal!(Const,"const");
re_terminal!(Crate,"crate");
re_terminal!(Extern,"extern");
re_terminal!(As,"as ");
re_terminal!(Struct,"struct");
re_terminal!(Enum,"enum ");
re_terminal!(Union,"union");
re_terminal!(Mod,"mod");
re_terminal!(Unsafe,"unsafe");
re_terminal!(FN,"fn ");
re_terminal!(Pub,"pub");
re_terminal!(LittleSelf,"self");
re_terminal!(Type,"type ");
re_terminal!(For,"for ");
re_terminal!(Trait,"trait");
re_terminal!(DEFAULT,"default");
re_terminal!(Impl,"impl");
re_terminal!(Where,"where");
re_terminal!(Super,"super");
re_terminal!(BOX,"box");
re_terminal!(Ref,"ref");
re_terminal!(Typeof,"typeof");
re_terminal!(StaticLifetime,"'static");
re_terminal!(Continue,"continue");
re_terminal!(Return,"return");
re_terminal!(Break,"break");
re_terminal!(Yield,"yield");
re_terminal!(Move,"move");
re_terminal!(Match,"match");
re_terminal!(If,"if");
re_terminal!(Else,"else");
re_terminal!(LiteralLet,"let");
re_terminal!(While,"while");
re_terminal!(Loop,"loop");
re_terminal!(In,"in ");
re_terminal!(True,"true");
re_terminal!(False,"false");
re_terminal!(Catch,"catch");
re_terminal!(Use,"use");
re_terminal!(Terminal,"terminal");
re_terminal!(Nonterminal,"nonterminal");
terminal ShebangLine
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,())>
{
None
//if parser.line_number>0
//{
// return None;
//}
//match parser.re("^#![^\n]*\n", source)
//{
// None => None,
// Some(size,string) => Some(size,()),
//}
}
}
re_terminal!(LitInteger(usize),"[0-9]+");
//terminal LitInteger(usize)
//{
// fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,usize)>
// {
// None
// // 0x[0-9a-fA-F_]+ { BEGIN(suffix); return LIT_INTEGER; }
// // 0o[0-7_]+ { BEGIN(suffix); return LIT_INTEGER; }
// // 0b[01_]+ { BEGIN(suffix); return LIT_INTEGER; }
// // [0-9][0-9_]* { BEGIN(suffix); return LIT_INTEGER; }
// // [0-9][0-9_]*\.(\.|[a-zA-Z]) { yyless(yyleng - 2); BEGIN(suffix); return LIT_INTEGER; }
// }
//}
terminal LitByte
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,())>
{
None
}
}
terminal LitChar(char)
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,char)>
{
let mut characters=source.chars();
if (characters.next())==(Some('\''))
{
let mut c=characters.next().unwrap();
let mut size=3;
if c=='\\'
{
c=(characters.next().unwrap());
size=4;
}
if characters.next().unwrap()=='\''
{
Some((size,c))
}
else
{
None
}
}
else
{
None
}
}
}
re_terminal!(LiteralLifetime(String),"'[a-zA-Z_]");
//terminal LiteralLifetime(String)
//{
// fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,String)>
// {
// None
// }
//}
terminal LitFloat
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,())>
{
None
}
}
terminal LitStr(String)
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,String)>
{
let mut ret=None;
let mut characters=source.chars();
if (characters.next())!=(Some('"'))
{
}
else
{
let mut size=1;
let mut r=String::from("\"");
while true
{
match characters.next()
{
None => break,
Some('"') =>
{
ret=(Some((size+1,r+&"\"")));
break;
},
Some('\\') =>
{
match characters.next()
{
None => break,
//Some(c) => r+='\\'+c,
Some(c) =>
{
r.push('\\');
r.push(c);
}
};
size+=2;
},
Some(c) =>
{
//r+=&String::from(c);
r.push(c);
size+=1;
},
};
}
}
ret
}
}
terminal LitStrRaw
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,())>
{
None
}
}
terminal LitByteStr
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,())>
{
None
}
}
terminal LitByteStrRaw
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,())>
{
None
}
}
terminal NoSpace
{
fn _match(parser: &mut Parser<Token,ParsingTables>, source:&str) -> Option<(usize,())>
{
None
}
}
re_terminal!(InnerDocComment,"\\\\![^\n]*\n");
re_terminal!(OuterDocComment(String),"\\\\\\[^\n]*\n");
re_terminal!(LiteralIdent(String),"[a-zA-Z\\x80-\\xff_][a-zA-Z0-9\\x80-\\xff_]*");
re_terminal!(Shebang,"#!");
re_terminal!(NumberSign,"#");
re_terminal!(FatArrow,"=>");
re_terminal!(EqualEqual,"==");
re_terminal!(NE,"!=");
re_terminal!(Equal,"=");
re_terminal!(LArrow,"<-");
re_terminal!(RArrow,"->");
//These cause many problems. Perhaps "<<" -> (LT,NOSPACE,LT)
//re_terminal!(SHL,"\\<\\<");
//re_terminal!(SHR,"\\>\\>");
//re_terminal!(SHREQ,"\\>\\>=");
re_terminal!(LE,"<=");
re_terminal!(GE,">=");
re_terminal!(MinusEqual,"-=");
re_terminal!(AndEqual,"&=");
re_terminal!(OrEqual,"\\|=");
re_terminal!(PlusEqual,"\\+=");
re_terminal!(StarEqual,"\\*=");
re_terminal!(SlashEqual,"/=");
re_terminal!(CaretEqual,"\\^=");
re_terminal!(PercentEqual,"%=");
re_terminal!(Underscore,"_");
re_terminal!(OrOr,"\\|\\|");
re_terminal!(Vertical,"\\|");
re_terminal!(Comma,",");
re_terminal!(AndAnd,"&&");
re_terminal!(Ampersand,"&");
re_terminal!(DotDotDot,"\\.\\.\\.");
re_terminal!(DotDot,"\\.\\.");
re_terminal!(Dot,"\\.");
re_terminal!(ModSep,"::");
re_terminal!(Colon,":");
re_terminal!(Caret,"\\^");
re_terminal!(Percent,"%");
re_terminal!(Semicolon,";");
re_terminal!(Bang,"!");
re_terminal!(At,"@");
re_terminal!(Star,"\\*");
re_terminal!(QuestionMark,"\\?");
re_terminal!(LBracket,"\\[");
re_terminal!(RBracket,"\\]");
re_terminal!(LPar,"\\(");
re_terminal!(RPar,"\\)");
re_terminal!(LBrace,"\\{");
re_terminal!(RBrace,"\\}");
re_terminal!(LT,"<");
re_terminal!(GT,">");
re_terminal!(Plus,"\\+");
re_terminal!(Minus,"-");
re_terminal!(_,"\\s+|\n|\\\\[^\n]*\n");//Otherwise skip spaces and normal comments
re_terminal!(Slash,"/");
////////////////////////////////////////////////////////////////////////
// Part 1: Items and attributes
////////////////////////////////////////////////////////////////////////
nonterminal WholeCrate(Vec<Rc<Token>>)
{
(MaybeShebang,InnerAttrs,MaybeModItems(ref items)) => items.clone(),
(MaybeShebang,MaybeModItems(ref items)) => items.clone(),
}
nonterminal MaybeShebang
{
(ShebangLine) => (),
() => (),
}
nonterminal MaybeInnerAttrs
{
(InnerAttrs) => (),
() => (),
}
nonterminal InnerAttrs
{
(InnerAttr) => (),
(InnerAttrs,InnerAttr) => (),
}
nonterminal InnerAttr
{
(Shebang,LBracket,MetaItem,RBracket) => (),
(InnerDocComment) => (),
}
nonterminal MaybeOuterAttrs(Vec<AttrKind>)
{
(OuterAttrs(ref attrs)) => attrs.clone(),
() => vec![],
}
nonterminal OuterAttrs(Vec<AttrKind>)
{
(OuterAttr(ref kind)) => vec![kind.clone()],
(OuterAttrs(ref attrs),OuterAttr(ref attr)) =>
{
let mut new=(attrs.clone());
new.push(attr.clone());
new
},
}
nonterminal OuterAttr(AttrKind)
{
(NumberSign,LBracket,MetaItem(ref attr),RBracket) => attr.clone(),
(OuterDocComment(ref string)) => AttrKind::Documentation(string.clone()),
}
nonterminal MetaItem(AttrKind)
{
(Ident(ref string)) => AttrKind::Flag(string.clone()),
(Ident(ref string),Equal,Lit(ref lit)) => AttrKind::Value(string.clone(),lit.clone()),
(Ident(ref string),LPar,MetaSeq(ref seq),RPar) => AttrKind::Sequence(string.clone(),seq.clone()),
(Ident(ref string),LPar,MetaSeq(ref seq),Comma,RPar) => AttrKind::Sequence(string.clone(),seq.clone()),
}
nonterminal MetaSeq(Vec<AttrKind>)
{
() => vec![],
(MetaItem(ref attr)) => vec![attr.clone()],
(MetaSeq(ref seq),Comma,MetaItem(ref attr)) =>
{
let mut new=(seq.clone());
new.push(attr.clone());
new
},
}
nonterminal MaybeModItems(Vec<Rc<Token>>)
{
(ModItems(ref items)) => items.clone(),
() => vec![],
}
nonterminal ModItems(Vec<Rc<Token>>)
{
(ModItem(ref outer,ref item)) => vec![Rc::new(Token::ModItem(outer.clone(),item.clone()))],
(ModItems(ref items),ModItem(ref outer,ref item)) =>
{
let mut new=(items.clone());
new.push(Rc::new(Token::ModItem(outer.clone(),item.clone())));
new
},
}
nonterminal AttrsAndVis(Vec<AttrKind>)
{
(MaybeOuterAttrs(ref attrs),Visibility) => attrs.clone(),
}
nonterminal ModItem(Vec<AttrKind>,ItemKind)
{
(AttrsAndVis(ref attrs),Item(ref item)) => (attrs.clone(),item.clone()),
}
// items that can appear outside of a fn block
nonterminal Item(ItemKind)
{
(StmtItem(ref item)) => item.clone(),
(ItemMacro(ref item)) => item.clone(),
}
// items that can appear in "stmts"
nonterminal StmtItem(ItemKind)
{
(ItemStatic) => ItemKind::Fixme,
(ItemConst) => ItemKind::Fixme,
(ItemType) => ItemKind::Fixme,
(BlockItem(ref item)) => item.clone(),
(ViewItem(ref view)) => ItemKind::View(view.clone()),
}
nonterminal ItemStatic
{
(Static,Ident,Colon,Ty,Equal,Expr,Semicolon) => (),
(Static,Mut,Ident,Colon,Ty,Equal,Expr,Semicolon) => (),
}
nonterminal ItemConst
{
(Const,Ident,Colon,Ty,Equal,Semicolon) => (),
}
nonterminal ItemMacro(ItemKind)
{
(PathExpr(ref s),Bang,MaybeIdent,ParensDelimitedTokenTrees(ref trees),Semicolon) => ItemKind::Macro(Rc::new(Token::PathExpr(s.clone())),None,Rc::new(Token::ParensDelimitedTokenTrees(trees.clone()))),
(PathExpr(ref s),Bang,MaybeIdent,BracesDelimitedTokenTrees(ref trees)) => ItemKind::Macro(Rc::new(Token::PathExpr(s.clone())),None,Rc::new(Token::BracesDelimitedTokenTrees(trees.clone()))),
(PathExpr(ref s),Bang,MaybeIdent,BracketsDelimitedTokenTrees(ref trees),Semicolon) => ItemKind::Macro(Rc::new(Token::PathExpr(s.clone())),None,Rc::new(Token::BracketsDelimitedTokenTrees(trees.clone()))),
}
nonterminal ViewItem(ViewKind)
{
(UseItem(ref view)) => view.clone(),
(ExternFnItem) => ViewKind::Fixme,
(Extern,Crate,Ident(ref string),Semicolon) => ViewKind::ExternCrate(string.clone(),None),
(Extern,Crate,Ident(ref string),As,Ident(ref string_as),Semicolon) => ViewKind::ExternCrate(string.clone(),Some(string_as.clone())),
}
nonterminal ExternFnItem
{
(Extern,MaybeAbi,ItemFn) => (),
}
nonterminal UseItem(ViewKind)
{
(Use,ViewPath(ref view),Semicolon) => view.clone(),
}
nonterminal ViewPath(ViewKind)
{
(PathNoTypesAllowed(ref path)) => ViewKind::Path(path.clone(),None),
(PathNoTypesAllowed(ref path),ModSep,LBrace,RBrace) => ViewKind::Selection(Some(path.clone()),vec![]),
(ModSep,LBrace,RBrace) => ViewKind::Selection(None,vec![]),
(PathNoTypesAllowed(ref path),ModSep,LBrace,IdentsOrSelf(ref idents),RBrace) => ViewKind::Selection(Some(path.clone()),idents.clone()),
(ModSep,LBrace,IdentsOrSelf(ref idents),RBrace) => ViewKind::Selection(None,idents.clone()),
(PathNoTypesAllowed(ref path),ModSep,LBrace,IdentsOrSelf(ref idents),Comma,RBrace) => ViewKind::Selection(Some(path.clone()),idents.clone()),
(ModSep,LBrace,IdentsOrSelf(ref idents),Comma,RBrace) => ViewKind::Selection(None,idents.clone()),//FIXME what is the point of :: ?
(PathNoTypesAllowed(ref path),ModSep,Star) => ViewKind::All(Some(path.clone())),
(ModSep,Star) => ViewKind::All(None),//FIXME what is this '::' ?
(Star) => ViewKind::All(None),
(LBrace,RBrace) => ViewKind::Selection(None,vec![]),
(LBrace,IdentsOrSelf(ref idents),RBrace) => ViewKind::Selection(None,idents.clone()),
(LBrace,IdentsOrSelf(ref idents),Comma,RBrace) => ViewKind::Selection(None,idents.clone()),
(PathNoTypesAllowed(ref path),As,Ident(ref string)) => ViewKind::Path(path.clone(),Some(string.clone())),
}
nonterminal BlockItem(ItemKind)
{
(ItemFn(ref item)) => item.clone(),
(ItemUnsafeFn) => ItemKind::Fixme,
(ItemMod) => ItemKind::Fixme,
(ItemForeignMod) => ItemKind::Fixme,
(ItemStruct(ref item)) => item.clone(),
(ItemEnum(ref item)) => item.clone(),
(ItemUnion) => ItemKind::Fixme,
(ItemTrait) => ItemKind::Fixme,
(ItemImpl(ref item)) => item.clone(),
(ItemTerminal(ref item)) => item.clone(),//NEW
(ItemNonterminal(ref item)) => item.clone(),//NEW
}
nonterminal MaybeTyAscription(Option<TyLf>)
{
(Colon,TySum(ref qtype)) => Some(qtype.clone()),
() => None,
}
nonterminal MaybeInitExpr(Option<ExprKind>)
{
(Equal,Expr(ref expr)) => Some(expr.clone()),
() => None,
}
//structs
nonterminal ItemStruct(ItemKind)
{
(Struct,Ident(ref name),GenericParams(ref lifetimes, ref gp),MaybeWhereClause,StructDeclArgs(ref fields)) => ItemKind::Struct(name.clone(),lifetimes.clone(),gp.clone(),fields.clone()),
(Struct,Ident,GenericParams,StructTupleArgs,MaybeWhereClause,Semicolon) => ItemKind::Fixme,
(Struct,Ident,GenericParams,MaybeWhereClause,Semicolon) => ItemKind::Fixme,
}
nonterminal StructDeclArgs(Vec<(String,TyLf)>)
{
(LBrace,StructDeclFields(ref fields),RBrace) => fields.clone(),
//(LBrace,StructDeclFields,RBrace,Comma) => (),//Wrong
(LBrace,StructDeclFields(ref fields),Comma,RBrace) => fields.clone(),
}
nonterminal StructTupleArgs
{
(LPar,StructTupleFields,RPar) => (),
(LPar,StructTupleFields,RPar,Comma) => (),
}
nonterminal StructDeclFields(Vec<(String,TyLf)>)
{
(StructDeclField(ref string, ref t)) => vec![(string.clone(),t.clone())],
(StructDeclFields(ref list),Comma,StructDeclField(ref string, ref t)) =>
{
let mut new=(list.clone());
new.push((string.clone(),t.clone()));
new
},
() => vec![],
}
nonterminal StructDeclField(String,TyLf)
{
(AttrsAndVis,Ident(ref string),Colon,TySum(ref t)) => (string.clone(),t.clone()),
}
nonterminal StructTupleFields
{
(StructTupleField) => (),
(StructTupleFields,Comma,StructTupleField) => (),
() => (),
}
nonterminal StructTupleField
{
(AttrsAndVis,TySum) => (),
}
// enums
nonterminal ItemEnum(ItemKind)
{
(Enum,Ident(ref id),GenericParams(ref lifetimes, ref params),MaybeWhereClause,LBrace,EnumDefs(ref defs),RBrace) => ItemKind::Enum(id.clone(),lifetimes.clone(),params.clone(),defs.clone()),
//(Enum,Ident,GenericParams,MaybeWhereClause,LBrace,EnumDefs,RBrace,Comma) => (),//Errata when copying
(Enum,Ident(ref id),GenericParams(ref lifetimes, ref params),MaybeWhereClause,LBrace,EnumDefs(ref defs),Comma,RBrace) => ItemKind::Enum(id.clone(),lifetimes.clone(),params.clone(),defs.clone()),
}
nonterminal EnumDefs(Vec<(String,Vec<TyLf>)>)
{
(EnumDef(ref id, ref arguments)) => vec![(id.clone(),arguments.clone())],
(EnumDefs(ref list),Comma,EnumDef(ref id, ref arguments)) =>
{
let mut new=(list.clone());
new.push((id.clone(),arguments.clone()));
new
},
() => vec![],
}
nonterminal EnumDef(String,Vec<TyLf>)
{
(AttrsAndVis,Ident(ref string),EnumArgs(ref arguments)) => (string.clone(),arguments.clone()),
}
nonterminal EnumArgs(Vec<TyLf>)
{
(LBrace,StructDeclFields,RBrace) => vec![],//FIXME
(LBrace,StructDeclFields,Comma,RBrace) => vec![],//FIXME
(LPar,MaybeTySums(ref list),RPar) => list.clone(),
(Equal,Expr) => vec![],//FIXME
() => vec![],
}
// unions
nonterminal ItemUnion
{
(Union,Ident,GenericParams,MaybeWhereClause,LBrace,StructDeclFields,RBrace) => (),
(Union,Ident,GenericParams,MaybeWhereClause,LBrace,StructDeclFields,Comma,RBrace) => (),
}
nonterminal ItemMod
{
(Mod,Ident,Semicolon) => (),
(Mod,Ident,LBrace,MaybeModItems,RBrace) => (),
(Mod,Ident,LBrace,InnerAttrs,MaybeModItems,RBrace) => (),
}
nonterminal ItemForeignMod
{
(Extern,MaybeAbi,LBrace,MaybeForeignItems,RBrace) => (),
(Extern,MaybeAbi,LBrace,InnerAttrs,MaybeForeignItems,RBrace) => (),
}
nonterminal MaybeAbi
{
(Str) => (),
() => (),
}
nonterminal MaybeForeignItems
{
(ForeignItems) => (),
() => (),
}
nonterminal ForeignItems
{
(ForeignItem) => (),
(ForeignItems,ForeignItem) => (),
}
nonterminal ForeignItem
{
(AttrsAndVis,Static,ItemForeignStatic) => (),
(AttrsAndVis,ItemForeignFn) => (),
(AttrsAndVis,Unsafe,ItemForeignFn) => (),
}
nonterminal ItemForeignStatic
{
(MaybeMut,Ident,Colon,Ty,Semicolon) => (),
}
nonterminal ItemForeignFn
{
(FN,Ident,GenericParams,FnDeclAllowVariadic,MaybeWhereClause,Semicolon) => (),
}
nonterminal FnDeclAllowVariadic
{
(FnParamsAllowVariadic,RetTy) => (),
}
nonterminal FnParamsAllowVariadic
{
(LPar,RPar) => (),
(LPar,Params,RPar) => (),
(LPar,Params,Comma,RPar) => (),
(LPar,Params,Comma,DotDotDot,RPar) => (),
}
nonterminal Visibility
{
(Pub) => (),
() => (),
}
nonterminal IdentsOrSelf(Vec<String>)
{
(IdentOrSelf(ref string)) => vec![string.clone()],
(IdentsOrSelf(ref list),As,Ident) => list.clone(),//FIXME
(IdentsOrSelf(ref list),Comma,IdentOrSelf(ref string)) =>
{
//let mut new=list.clone();//FIXME
let mut new=(list.clone());
new.push(string.clone());
new
},
}
nonterminal IdentOrSelf(String)
{
(Ident(ref string)) => string.clone(),
(LittleSelf) => String::from("self"),
}
nonterminal ItemType
{
(Type,Ident,GenericParams,MaybeWhereClause,Equal,TySum,Semicolon) => (),
}
nonterminal ForSized
{
(For,QuestionMark,Ident) => (),
(For,Ident,QuestionMark) => (),
() => (),
}
nonterminal ItemTrait
{
(MaybeUnsafe,Trait,Ident,GenericParams,ForSized,MaybeTyParamBounds,MaybeWhereClause,LBrace,MaybeTraitItems,RBrace) => (),
}
nonterminal MaybeTraitItems
{
(TraitItems) => (),
() => (),
}
nonterminal TraitItems
{
(TraitItem) => (),
(TraitItems,TraitItem) => (),
}
nonterminal TraitItem
{
(TraitConst) => (),
(TraitType) => (),
(TraitMethod) => (),
(MaybeOuterAttrs,ItemMacro) => (),
}
nonterminal TraitConst
{
(MaybeOuterAttrs,Const,Ident,MaybeTyAscription,MaybeConstDefault,Semicolon) => (),
}
nonterminal MaybeConstDefault
{
(Equal,Expr) => (),
() => (),
}
nonterminal TraitType
{
(MaybeOuterAttrs,Type,TyParam,Semicolon) => (),
}
nonterminal MaybeUnsafe
{
(Unsafe) => (),
() => (),
}
nonterminal MaybeDefaultMaybeUnsafe
{
(DEFAULT,Unsafe) => (),
(Unsafe) => (),
(Unsafe) => (),
() => (),
}
nonterminal TraitMethod
{
(TypeMethod) => (),
(Method) => (),
}
nonterminal TypeMethod
{
(MaybeOuterAttrs,MaybeUnsafe,FN,Ident,GenericParams,FnDeclWithSelfAllowAnonParams,MaybeWhereClause,Semicolon) => (),
(MaybeOuterAttrs,Const,MaybeUnsafe,FN,Ident,GenericParams,FnDeclWithSelfAllowAnonParams,MaybeWhereClause,Semicolon) => (),
(MaybeOuterAttrs,MaybeUnsafe,Extern,MaybeAbi,FN,Ident,GenericParams,FnDeclWithSelfAllowAnonParams,MaybeWhereClause,Semicolon) => (),
}
nonterminal Method
{
(MaybeOuterAttrs,MaybeUnsafe,FN,Ident,GenericParams,FnDeclWithSelfAllowAnonParams,MaybeWhereClause,InnerAttrsAndBlock) => (),
(MaybeOuterAttrs,Const,MaybeUnsafe,FN,Ident,GenericParams,FnDeclWithSelfAllowAnonParams,MaybeWhereClause,InnerAttrsAndBlock) => (),
(MaybeOuterAttrs,MaybeUnsafe,Extern,MaybeAbi,FN,Ident,GenericParams,FnDeclWithSelfAllowAnonParams,MaybeWhereClause,InnerAttrsAndBlock) => (),
}
nonterminal ImplMethod(ItemKind)
{
(AttrsAndVis,MaybeDefault,MaybeUnsafe,FN,Ident(ref name),GenericParams(ref lifetimes,ref gp),FnDeclWithSelf(has_self, has_ref, has_mut, ref ot_self, ref params, ref oret),MaybeWhereClause,InnerAttrsAndBlock(ref stmts,ref be)) =>
ItemKind::Method(name.clone(),lifetimes.clone(),gp.clone(),has_self,has_ref,has_mut,ot_self.clone(),params.clone(),oret.clone(),stmts.clone(),be.clone()),
(AttrsAndVis,MaybeDefault,Const,MaybeUnsafe,FN,Ident,GenericParams,FnDeclWithSelf,MaybeWhereClause,InnerAttrsAndBlock) => ItemKind::Fixme,
(AttrsAndVis,MaybeDefault,MaybeUnsafe,Extern,MaybeAbi,FN,Ident,GenericParams,FnDeclWithSelf,MaybeWhereClause,InnerAttrsAndBlock) => ItemKind::Fixme,
}
// --- BISON NOTES ---
// There are two forms of impl:
//
// impl (<...>)? TY { ... }
// impl (<...>)? TRAIT for TY { ... }
//
// Unfortunately since TY can begin with '<' itself -- as part of a
// TyQualifiedPath type -- there's an s/r conflict when we see '<' after IMPL:
// should we reduce one of the early rules of TY (such as maybe_once)
// or shall we continue shifting into the generic_params list for the
// impl?
//
// The production parser disambiguates a different case here by
// permitting / requiring the user to provide parens around types when
// they are ambiguous with traits. We do the same here, regrettably,
// by splitting ty into ty and ty_prim.
nonterminal ItemImpl(ItemKind)
{
(MaybeDefaultMaybeUnsafe,Impl,GenericParams(ref lifetimes,ref gp),TyPrimSum(ref t),MaybeWhereClause,LBrace,MaybeInnerAttrs,MaybeImplItems(ref items),RBrace) =>
ItemKind::Impl(lifetimes.clone(),gp.clone(),None,t.clone(),items.clone()),
(MaybeDefaultMaybeUnsafe,Impl,GenericParams,LPar,Ty,RPar,MaybeWhereClause,LBrace,MaybeInnerAttrs,MaybeImplItems,RBrace) => ItemKind::Fixme,
(MaybeDefaultMaybeUnsafe,Impl,GenericParams(ref lifetimes, ref gp),TraitRef(ref path),For,TySum(ref t),MaybeWhereClause,LBrace,MaybeInnerAttrs,MaybeImplItems(ref items),RBrace) =>
ItemKind::Impl(lifetimes.clone(),gp.clone(),Some(path.clone()),t.clone(),items.clone()),
(MaybeDefaultMaybeUnsafe,Impl,GenericParams,Bang,TraitRef,For,TySum,MaybeWhereClause,LBrace,MaybeInnerAttrs,MaybeImplItems,RBrace) => ItemKind::Fixme,
(MaybeDefaultMaybeUnsafe,Impl,GenericParams,TraitRef,For,DotDot,LBrace,RBrace) => ItemKind::Fixme,
(MaybeDefaultMaybeUnsafe,Impl,GenericParams,Bang,TraitRef,For,DotDot,LBrace,RBrace) => ItemKind::Fixme,
}
nonterminal MaybeImplItems(Vec<ItemKind>)
{
(ImplItems(ref items)) => items.clone(),
() => vec![],
}
nonterminal ImplItems(Vec<ItemKind>)
{
(ImplItem(ref item)) => vec![item.clone()],
(ImplItem(ref item),ImplItems(ref list)) =>
{
let mut new=vec![item.clone()];
//new.extend(list);
new.extend(list.iter().map( |x|(x.clone()) ));
new
},
}
nonterminal ImplItem(ItemKind)
{
(ImplMethod(ref item)) => item.clone(),
(AttrsAndVis,ItemMacro) => ItemKind::Fixme,
(ImplConst) => ItemKind::Fixme,
(ImplType) => ItemKind::Fixme,
}
nonterminal MaybeDefault
{
(DEFAULT) => (),
() => (),
}
nonterminal ImplConst
{
(AttrsAndVis,MaybeDefault,ItemConst) => (),
}
nonterminal ImplType
{
(AttrsAndVis,MaybeDefault,Type,Ident,GenericParams,Equal,TySum,Semicolon) => (),
}
nonterminal ItemFn(ItemKind)
{
(FN,Ident(ref name),GenericParams(ref lives, ref gp),FnDecl(ref params,ref rt),MaybeWhereClause,InnerAttrsAndBlock(ref block_stmts, ref block_expr)) =>
(ItemKind::FN(name.clone(),lives.clone(),gp.clone(),params.clone(),rt.clone(),block_stmts.clone(),block_expr.clone())),
(Const,FN,Ident(ref name),GenericParams(ref lives, ref gp),FnDecl(ref params,ref rt),MaybeWhereClause,InnerAttrsAndBlock(ref block_stmts, ref block_expr)) =>
(ItemKind::FN(name.clone(),lives.clone(),gp.clone(),params.clone(),rt.clone(),block_stmts.clone(),block_expr.clone())),
}
nonterminal ItemUnsafeFn
{
(Unsafe,FN,Ident,GenericParams,FnDecl,MaybeWhereClause,InnerAttrsAndBlock) => (),
(Const,Unsafe,FN,Ident,GenericParams,FnDecl,MaybeWhereClause,InnerAttrsAndBlock) => (),
(Unsafe,Extern,MaybeAbi,FN,Ident,GenericParams,FnDecl,MaybeWhereClause,InnerAttrsAndBlock) => (),
}
nonterminal FnDecl(Vec<(PatKind,TyLf)>,Option<TyKind>)
{
(FnParams(ref params),RetTy(ref ot)) => (params.clone(),ot.clone()),
}
nonterminal FnDeclWithSelf(bool,bool,bool,Option<TyLf>,Vec<(PatKind,TyLf)>,Option<TyKind>)
{
(FnParamsWithSelf(has_self, has_ref, has_mut, ref ot_self, ref params),RetTy(ref oret)) =>
(has_self,has_ref,has_mut,ot_self.clone(),params.clone(),oret.clone()),
}
nonterminal FnDeclWithSelfAllowAnonParams
{
(FnAnonParamsWithSelf,RetTy) => (),
}
nonterminal FnParams(Vec<(PatKind,TyLf)>)
{
(LPar,MaybeParams(ref params),RPar) => params.clone(),
}
nonterminal FnAnonParams
{
(LPar,AnonParam,AnonParamsAllowVariadicTail,RPar) => (),
(LPar,RPar) => (),
}
nonterminal FnParamsWithSelf(bool,bool,bool,Option<TyLf>,Vec<(PatKind,TyLf)>)//has self, has &, has mut, self_type, other_params
{
(LPar,MaybeMut(ismut),LittleSelf,MaybeTyAscription(ref ot),MaybeCommaParams(ref params),RPar) =>
(true,false,ismut,ot.clone(),params.clone()),
(LPar,Ampersand,MaybeMut(ismut),LittleSelf,MaybeTyAscription(ref ot),MaybeCommaParams(ref params),RPar) =>
(true,true,ismut,ot.clone(),params.clone()),
(LPar,Ampersand,Lifetime,MaybeMut(ismut),LittleSelf,MaybeTyAscription(ref ot),MaybeCommaParams(ref params),RPar) =>
(true,true,ismut,ot.clone(),params.clone()),//FIXME: lifetime
(LPar,MaybeParams(ref params),RPar) => (false,false,false,None,params.clone()),
}
nonterminal FnAnonParamsWithSelf
{
(LPar,MaybeMut,LittleSelf,MaybeTyAscription,MaybeCommaAnonParams,RPar) => (),
(LPar,Ampersand,MaybeMut,LittleSelf,MaybeTyAscription,MaybeCommaAnonParams,RPar) => (),
(LPar,Ampersand,Lifetime,MaybeMut,LittleSelf,MaybeTyAscription,MaybeCommaAnonParams,RPar) => (),
(LPar,MaybeAnonParams,RPar) => (),
}
nonterminal MaybeParams(Vec<(PatKind,TyLf)>)
{
(Params(ref params)) => params.clone(),
(Params(ref params),Comma) => params.clone(),
() => vec![],
}
nonterminal Params(Vec<(PatKind,TyLf)>)
{
(Param(ref pattern, ref t)) => vec![(pattern.clone(),t.clone())],
(Params(ref list),Comma,Param(ref pattern, ref t)) =>
{
let mut new=(list.clone());
new.push((pattern.clone(),t.clone()));
new
},
}
nonterminal Param(PatKind,TyLf)
{
(Pat(ref pattern),Colon,TySum(ref t)) => (pattern.clone(),t.clone()),
}
nonterminal InferrableParams(Vec<(PatKind,Option<TyLf>)>)
{
(InferrableParam(ref pattern, ref ot)) => (vec![(pattern.clone(),ot.clone())]),
(InferrableParams(ref params),Comma,InferrableParam(ref pattern, ref ot)) =>
{
let mut new=(params.clone());
new.push((pattern.clone(),ot.clone()));
new
},
}
nonterminal InferrableParam(PatKind,Option<TyLf>)
{
(Pat(ref pat),MaybeTyAscription(ref ot)) => (pat.clone(),ot.clone()),
}
nonterminal MaybeCommaParams(Vec<(PatKind,TyLf)>)
{
(Comma) => vec![],
(Comma,Params(ref params)) => params.clone(),
(Comma,Params(ref params),Comma) => params.clone(),
() => vec![],
}
nonterminal MaybeCommaAnonParams
{
(Comma) => (),
(Comma,AnonParams) => (),
(Comma,AnonParams,Comma) => (),
() => (),
}
nonterminal MaybeAnonParams
{
(AnonParams) => (),
(AnonParams, Comma) => (),
() => (),
}
nonterminal AnonParams
{
(AnonParam) => (),
(AnonParams,Comma,AnonParam) => (),
}
// anon means it's allowed to be anonymous (type-only), but it can
// still have a name
nonterminal AnonParam
{
(NamedArg,Colon,Ty) => (),
(Ty) => (),
}
nonterminal AnonParamsAllowVariadicTail
{
(Comma,DotDotDot) => (),
(Comma,AnonParam,AnonParamsAllowVariadicTail) => (),
() => (),
}
nonterminal NamedArg
{
(Ident) => (),
(Underscore) => (),
(Ampersand,Ident) => (),
(Ampersand,Underscore) => (),
(AndAnd,Ident) => (),
(AndAnd,Underscore) => (),
(Mut,Ident) => (),
}
nonterminal RetTy(Option<TyKind>)
{
(RArrow,Bang) => Some(TyKind::Fixme),
(RArrow,Ty(ref t)) => Some(t.clone()),
() => None,
}
nonterminal GenericParams(Vec<String>,Vec<String>)
{
(LT,GT,MaybeSpace) => (vec![],vec![]),
(LT,Lifetimes(ref lives),GT,MaybeSpace) => (lives.clone(),vec![]),
(LT,Lifetimes(ref lives),Comma,GT,MaybeSpace) => (lives.clone(),vec![]),
//(LT,Lifetimes,SHR) => (),
//(LT,Lifetimes,Comma,SHR) => (), //Tricky with bison: push_back('>');
(LT,Lifetimes(ref lives),Comma,TyParams(ref params),GT,MaybeSpace) => (lives.clone(),params.clone()),
(LT,Lifetimes(ref lives),Comma,TyParams(ref params),Comma,GT,MaybeSpace) => (lives.clone(),params.clone()),
//(LT,Lifetimes,Comma,TyParams(ref params),SHR) => (),
//(LT,Lifetimes,Comma,TyParams(ref params),COMMA,SHR) => (),
(LT,TyParams(ref params),GT) => (vec![],params.clone()),
(LT,TyParams(ref params),Comma,GT) => (vec![],params.clone()),
//(LT,TyParams,SHR) => (),
//(LT,TyParams,Comma,SHR) => (),
() => (vec![],vec![]),
}
nonterminal MaybeWhereClause
{
() => (),
(WhereClause) => (),
}
nonterminal WhereClause
{
(Where,WherePredicates) => (),
(Where,WherePredicates,Comma) => (),
}
nonterminal WherePredicates
{
(WherePredicate) => (),
(WherePredicates,Comma,WherePredicate) => (),
}
nonterminal WherePredicate
{
(MaybeForLifetimes,Lifetime,Colon,Bounds) => (),
(MaybeForLifetimes,Ty,Colon,TyParamBounds) => (),
}
nonterminal MaybeForLifetimes
{
(For,LT,Lifetimes,GT) => (),
() => (), //bison precedence of FORTYPE
}
nonterminal TyParams(Vec<String>)
{
(TyParam(ref param)) => vec![param.clone()],
(TyParams(ref list),Comma,TyParam(ref param)) =>
{
let mut new=(list.clone());
new.push(param.clone());
new
},
}
// A path with no type parameters; e.g. `foo::bar::Baz`
//
// These show up in 'use' view-items, because these are processed
// without respect to types.
nonterminal PathNoTypesAllowed(PathNKind)
{
(Ident(ref string)) => PathNKind::Ident(string.clone()),
(ModSep,Ident(ref string)) => PathNKind::AbsoluteIdent(string.clone()),
(LittleSelf) => PathNKind::FromSelf,
(ModSep,LittleSelf) => PathNKind::AbsoluteSelf,
(Super) => PathNKind::Super,
(ModSep,Super) => PathNKind::AbsoluteSuper,
(PathNoTypesAllowed(ref path),ModSep,Ident(ref string)) => PathNKind::Step(Rc::new(path.clone()),string.clone()),
}
// A path with a lifetime and type parameters, with no double colons
// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`
//
// These show up in "trait references", the components of
// type-parameter bounds lists, as well as in the prefix of the
// path_generic_args_and_bounds rule, which is the full form of a
// named typed expression.
//
// They do not have (nor need) an extra '::' before '<' because
// unlike in expr context, there are no "less-than" type exprs to
// be ambiguous with.
nonterminal PathGenericArgsWithoutColons(PathWKind)
{
(Ident(ref string)) => PathWKind::Ident(string.clone()),
(Ident(ref string),GenericArgs(ref gens)) => PathWKind::IdentGeneric(string.clone(),gens.clone()),
(Ident(ref string),LPar,MaybeTySums(ref list),RPar,RetTy) => PathWKind::Function(string.clone(),list.clone(),Rc::new(state.values[4].clone())),
(PathGenericArgsWithoutColons(ref path),ModSep,Ident(ref string)) => PathWKind::StepIdent(Rc::new(path.clone()),string.clone()),
(PathGenericArgsWithoutColons(ref path),ModSep,Ident(ref string),GenericArgs(ref gens)) => PathWKind::StepIdentGeneric(Rc::new(path.clone()),string.clone(),gens.clone()),
(PathGenericArgsWithoutColons(ref path),ModSep,Ident(ref string),LPar,MaybeTySums(ref list),RPar,RetTy) => PathWKind::StepFunction(Rc::new(path.clone()),string.clone(),list.clone(),Rc::new(state.values[6].clone())),
}
nonterminal GenericArgs(Vec<TyLf>)
{
(LT,MaybeSpace,GenericValues(ref list),GT,MaybeSpace) => list.clone(),
//(LT,GenericValues,SHR) => (), //push_back magic
(LT,MaybeSpace,GenericValues(ref list),GE,MaybeSpace) => list.clone(),
//(LT,GenericValues,SHREQ) => (),
//(SHL,TyQualifiedPathAndGenericValues,GT) => (),
//(SHL,TyQualifiedPathAndGenericValues,SHR) => (),
//(SHL,TyQualifiedPathAndGenericValues,GE) => (),
//(SHL,TyQualifiedPathAndGenericValues,SHREQ) => (),
}
nonterminal GenericValues(Vec<TyLf>)
{
(MaybeTySumsAndOrBindings(ref list)) => list.clone(),
}
nonterminal MaybeTySumsAndOrBindings(Vec<TyLf>)
{
(TySums(ref list)) => list.clone(),
(TySums(ref list),Comma) => list.clone(),
(TySums(ref list),Comma,Bindings) => list.clone(),
(Bindings) => vec![],
(Bindings,Comma) => vec![],
() => vec![],
}
nonterminal MaybeBindings
{
(Comma,Bindings) => (),
() => (),
}
////////////////////////////////////////////////////////////////////////
// Part 2: Patterns
////////////////////////////////////////////////////////////////////////
nonterminal Pat(PatKind)
{
(Underscore) => PatKind::Underscore,
(Ampersand,Pat(ref kind)) => PatKind::Ref(Rc::new(kind.clone())),
(Ampersand,Mut,Pat(ref kind)) => PatKind::RefMut(Rc::new(kind.clone())),
(AndAnd,Mut,Pat(ref kind)) => PatKind::Ref(Rc::new(PatKind::RefMut(Rc::new(kind.clone())))),
(LPar,RPar) => PatKind::Void,
(LPar,PatTup(ref patterns),RPar) => PatKind::Tuple(patterns.clone()),
(LBracket,PatVec,RBracket) => PatKind::Fixme,
(LitOrPath(ref path)) => PatKind::Path(path.clone()),
(LitOrPath,DotDotDot,LitOrPath) => PatKind::Fixme,
(PathExpr,LBrace,PatStruct,RBrace) => PatKind::Fixme,
(PathExpr,LPar,RPar) => PatKind::EnumEmpty(Rc::new(state.values[0].clone())),
(PathExpr,LPar,PatTup(ref patterns),RPar) => PatKind::Enum(Rc::new(state.values[0].clone()),patterns.clone()),
(PathExpr,Bang,MaybeIdent,DelimitedTokenTrees) => PatKind::Fixme,
(BindingMode(ref bind),Ident(ref string)) => PatKind::BindedIdent(bind.clone(),string.clone()),
(Ident,At,Pat) => PatKind::Fixme,
(BindingMode,Ident,At,Pat) => PatKind::Fixme,
(BOX,Pat) => PatKind::Fixme,
(LT,TySum,MaybeAsTraitRef,GT,ModSep,Ident) => PatKind::Fixme,
//(SHL,TySum,MaybeAsTraitRef,GT,ModSep,Ident,MaybeAsTraitRef,GT,ModSep,Ident) => (),
}
nonterminal PatsOr(PatKind)
{
//(Pat) => Rc::new(state.values[0].clone()),
(Pat(ref kind)) => kind.clone(),
(PatsOr(ref kind),Vertical,Pat) => kind.clone(),//FIXME
}
nonterminal BindingMode(BindKind)
{
(Ref) => BindKind::Ref,
(Ref,Mut) => BindKind::RefMut,
(Mut) => BindKind::Mut,
}
nonterminal LitOrPath(PathKind)
{
(PathExpr(ref path)) => path.clone(),
(Lit(ref token)) => PathKind::Literal(token.clone()),
(Minus,Lit) => PathKind::Fixme,
}
nonterminal PatField
{
(Ident) => (),
(BindingMode,Ident) => (),
(BOX,Ident) => (),
(BOX,BindingMode,Ident) => (),
(Ident,Colon,Pat) => (),
(BindingMode,Ident,Colon,Pat) => (),
(LitInteger,Colon,Pat) => (),
}
nonterminal PatFields
{
(PatField) => (),
(PatFields,Comma,PatField) => (),
}
nonterminal PatStruct
{
(PatFields) => (),
(PatFields,Comma) => (),
(PatFields,Comma,DotDot) => (),
(DotDot) => (),
() => (),
}
nonterminal PatTup(Vec<PatKind>)
{
(PatTupElts(ref elements)) => elements.clone(),
(PatTupElts(ref elements),Comma) => elements.clone(),
(PatTupElts(ref elements),DotDot) => vec![],//FIXME
(PatTupElts(ref elements),Comma,DotDot) => vec![],//FIXME
(PatTupElts(ref elements),DotDot,Comma,PatTupElts) => vec![],//FIXME
(PatTupElts(ref elements),DotDot,Comma,PatTupElts,Comma) => vec![],//FIXME
(PatTupElts(ref elements),Comma,DotDot,Comma,PatTupElts) => vec![],//FIXME
(PatTupElts(ref elements),Comma,DotDot,Comma,PatTupElts,Comma) => vec![],//FIXME
(DotDot,Comma,PatTupElts) => vec![],//FIXME
(DotDot,Comma,PatTupElts,Comma) => vec![],//FIXME
(DotDot) => vec![],//FIXME
}
nonterminal PatTupElts(Vec<PatKind>)
{
(Pat(ref pattern)) => vec![pattern.clone()],
(PatTupElts(ref elements),Comma,Pat(ref pattern)) =>
{
let mut new=(elements.clone());
new.push(pattern.clone());
new
},
}
nonterminal PatVec
{
(PatVecElts) => (),
(PatVecElts,Comma) => (),
(PatVecElts,DotDot) => (),
(PatVecElts,Comma,DotDot) => (),
(PatVecElts,DotDot,Comma,PatVecElts) => (),
(PatVecElts,DotDot,Comma,PatVecElts,Comma) => (),
(PatVecElts,Comma,DotDot,Comma,PatVecElts) => (),
(PatVecElts,Comma,DotDot,Comma,PatVecElts,Comma) => (),
(DotDot,Comma,PatVecElts) => (),
(DotDot,Comma,PatVecElts,Comma) => (),
(DotDot) => (),
() => (),
}
nonterminal PatVecElts
{
(Pat) => (),
(PatVecElts,Comma,Pat) => (),
}
////////////////////////////////////////////////////////////////////////
// Part 3: Types
////////////////////////////////////////////////////////////////////////
nonterminal Ty(TyKind)
{
(TyPrim(ref kind)) => kind.clone(),
(TyClosure) => TyKind::Fixme,
(LT,TySum,MaybeAsTraitRef,GT,ModSep,Ident) => TyKind::Fixme,
//(SHL,TySum,MaybeAsTraitRef,GT,ModSep,Ident,MaybeAsTraitRef,GT,ModSep,Ident) => (),
(LPar,TySums(ref list),RPar) => TyKind::Tuple(list.clone()),
(LPar,TySums(ref list),Comma,RPar) => TyKind::Tuple(list.clone()),
(LPar,RPar) => TyKind::Void,
}
nonterminal TyPrim(TyKind)
{
(PathGenericArgsWithoutColons(ref string)) => TyKind::Path(string.clone()),
(ModSep,PathGenericArgsWithoutColons) => TyKind::Fixme,
(LittleSelf,ModSep,PathGenericArgsWithoutColons) => TyKind::Fixme,
(PathGenericArgsWithoutColons,Bang,MaybeIdent,DelimitedTokenTrees) => TyKind::Fixme,
(ModSep,PathGenericArgsWithoutColons,Bang,MaybeIdent,DelimitedTokenTrees) => TyKind::Fixme,
(BOX,Ty) => TyKind::Fixme,
(Star,MaybeMutOrConst,Ty) => TyKind::Fixme,
(Ampersand,Ty(ref kind)) => TyKind::Ref(Rc::new(kind.clone())),
(Ampersand,Mut,Ty(ref kind)) => TyKind::RefMut(Rc::new(kind.clone())),
(AndAnd,Ty) => TyKind::Fixme,
(AndAnd,Mut,Ty) => TyKind::Fixme,
(Ampersand,Lifetime(ref lifetime),MaybeMut(ismut),Ty(ref t)) => TyKind::RefLifetime(lifetime.clone(),ismut,Rc::new(t.clone())),
(LBracket,Ty,RBracket) => TyKind::Fixme,
(LBracket,Ty,Comma,DotDot,Expr,RBracket) => TyKind::Fixme,
(LBracket,Ty,Semicolon,Expr,RBracket) => TyKind::Fixme,
(Typeof,LPar,Expr,RPar) => TyKind::Fixme,
(Underscore) => TyKind::Underscore,
(TyBareFn) => TyKind::Fixme,
(ForInType) => TyKind::Fixme,
}
nonterminal TyBareFn
{
(FN,TyFnDecl) => (),
(Unsafe,FN,TyFnDecl) => (),
(Extern,FN,TyFnDecl) => (),
(Unsafe,Extern,FN,TyFnDecl) => (),
}
nonterminal TyFnDecl
{
(GenericParams,FnAnonParams,RetTy) => (),
}
nonterminal TyClosure
{
(Unsafe,Vertical,AnonParams,Vertical,MaybeBounds,RetTy) => (),
(Vertical,AnonParams,Vertical,MaybeBounds,RetTy) => (),
(Unsafe,OrOr,MaybeBounds,RetTy) => (),
(OrOr,MaybeBounds,RetTy) => (),
}
nonterminal ForInType
{
(For,LT,MaybeLifetimes,GT,ForInTypeSuffix) => (),
}
nonterminal ForInTypeSuffix
{
(TyBareFn) => (),
(TraitRef) => (),
(TyClosure) => (),
}
nonterminal MaybeMut(bool)
{
(Mut) => true,
() => false,
}
nonterminal MaybeMutOrConst
{
(Mut) => (),
(Const) => (),
() => (),
}
nonterminal TyQualifiedPathAndGenericValues
{
(TyQualifiedPath,MaybeBindings) => (),
(TyQualifiedPath,Comma,TySums,MaybeBindings) => (),
}
nonterminal TyQualifiedPath
{
(TySums,As,TraitRef,GT,ModSep,Ident) => (),
(TySums,As,TraitRef,GT,ModSep,Ident,Plus,TyParamBounds) => (),
}
nonterminal MaybeTySums(Vec<TyLf>)
{
(TySums(ref qtypes)) => qtypes.clone(),
(TySums(ref qtypes),Comma) => qtypes.clone(),
() => vec![],
}
nonterminal TySums(Vec<TyLf>)
{
(TySum(ref t)) => vec![t.clone()],
(TySums(ref qtypes),Comma,TySum(ref t)) =>
{
let mut new=(qtypes.clone());
new.push(t.clone());
new
},
}
nonterminal TySum(TyLf)
{
(TySumElt(ref kind)) => kind.clone(),
(TySum(ref kind),Plus,TySumElt) => kind.clone(),//FIXME
}
nonterminal TySumElt(TyLf)
{
(Ty(ref kind)) => TyLf::Type(kind.clone()),
(Lifetime(ref string)) => TyLf::Lifetime(string.clone()),
}
nonterminal TyPrimSum(TyLf)
{
(TyPrimSumElt(ref t)) => t.clone(),
(TyPrimSum(ref t),Plus,TyPrimSumElt) => t.clone(),//FIXME
}
nonterminal TyPrimSumElt(TyLf)
{
(TyPrim(ref t)) => TyLf::Type(t.clone()),
(Lifetime(ref lifetime)) => TyLf::Lifetime(lifetime.clone()),
}
nonterminal MaybeTyParamBounds
{
(Colon,TyParamBounds) => (),
() => (),
}
nonterminal TyParamBounds
{
(Boundseq) => (),
() => (),
}
nonterminal Boundseq
{
(Polybound) => (),
(Boundseq,Plus,Polybound) => (),
}
nonterminal Polybound
{
(For,LT,MaybeLifetimes,GT,Bound) => (),
(Bound) => (),
(QuestionMark,For,LT,MaybeLifetimes,GT,Bound) => (),
(QuestionMark,Bound) => (),
}
nonterminal Bindings
{
(Binding) => (),
(Bindings,Comma,Binding) => (),
}
nonterminal Binding
{
(Ident,Equal,Ty) => (),
}
nonterminal TyParam(String)
{
(Ident(ref s),MaybeTyParamBounds,MaybeTyDefault) => s.clone(),//FIXME
(Ident(ref s),QuestionMark,Ident,MaybeTyParamBounds,MaybeTyDefault) => s.clone(),//FIXME
}
nonterminal MaybeBounds
{
(Colon,Bounds) => (),
() => (),
}
nonterminal Bounds
{
(Bounds) => (),
(Bounds,Plus,Bound) => (),
}
nonterminal Bound
{
(Lifetime) => (),
(TraitRef) => (),
}
nonterminal MaybeLTBounds
{
(Colon,LTBounds) => (),
() => (),
}
nonterminal LTBounds
{
(Lifetime) => (),
(LTBounds,Plus,Lifetime) => (),
}
nonterminal MaybeTyDefault
{
(Equal,TySum) => (),
() => (),
}
nonterminal MaybeLifetimes
{
(Lifetimes) => (),
(Lifetimes,Comma) => (),
() => (),
}
nonterminal Lifetimes(Vec<String>)
{
(LifetimeAndBounds(ref string)) => vec![string.clone()],
(Lifetimes(ref list),Comma,LifetimeAndBounds(ref lifetime)) =>
{
let mut new=(list.clone());
new.push(lifetime.clone());
new
},
}
nonterminal LifetimeAndBounds(String)
{
(LiteralLifetime(ref string),MaybeLTBounds) => string.clone(),
(StaticLifetime) => String::from("'static"),
}
nonterminal Lifetime(String)
{
(LiteralLifetime(ref string)) => string.clone(),
(StaticLifetime) => String::from("'static"),
}
nonterminal TraitRef(PathWKind)
{
(PathGenericArgsWithoutColons(ref path)) => path.clone(),
(ModSep,PathGenericArgsWithoutColons(ref path)) => path.clone(),
}
////////////////////////////////////////////////////////////////////////
// Part 4: Blocks, statements, and expressions
////////////////////////////////////////////////////////////////////////
nonterminal InnerAttrsAndBlock(Vec<StmtKind>,Option<ExprKind>)
{
(LBrace,MaybeInnerAttrs,MaybeStmts(ref stmts, ref oe),RBrace) => (stmts.clone(),oe.clone()),
}
nonterminal Block(Vec<StmtKind>,Option<ExprKind>)
{
(LBrace,MaybeStmts(ref list,ref option),RBrace) => (list.clone(),option.clone()),
}
nonterminal MaybeStmts(Vec<StmtKind>,Option<ExprKind>)
{
(Stmts(ref list)) => (list.clone(),None),
(Stmts(ref list),NonblockExpr(ref expr)) => (list.clone(),Some(expr.clone())),
(NonblockExpr(ref expr)) => (vec![],Some(expr.clone())),
() => (vec![],None),
}
// --- BISON NOTES ---
// There are two sub-grammars within a "stmts: exprs" derivation
// depending on whether each stmt-expr is a block-expr form; this is to
// handle the "semicolon rule" for stmt sequencing that permits
// writing
//
// if foo { bar } 10
//
// as a sequence of two stmts (one if-expr stmt, one lit-10-expr
// stmt). Unfortunately by permitting juxtaposition of exprs in
// sequence like that, the non-block expr grammar has to have a
// second limited sub-grammar that excludes the prefix exprs that
// are ambiguous with binops. That is to say:
//
// {10} - 1
//
// should parse as (progn (progn 10) (- 1)) not (- (progn 10) 1), that
// is to say, two statements rather than one, at least according to
// the mainline rust parser.
//
// So we wind up with a 3-way split in exprs that occur in stmt lists:
// block, nonblock-prefix, and nonblock-nonprefix.
//
// In non-stmts contexts, expr can relax this trichotomy.
nonterminal Stmts(Vec<StmtKind>)
{
(Stmt(ref stmt)) => vec![stmt.clone()],
(Stmts(ref stmts),Stmt(ref stmt)) =>
{
let mut new=(stmts.clone());
new.push(stmt.clone());
new
},
}
nonterminal Stmt(StmtKind)
{
(MaybeOuterAttrs,Let(ref stmt)) => stmt.clone(),
(StmtItem(ref item)) => StmtKind::Item(vec![],item.clone()),
(Pub,StmtItem(ref item)) => StmtKind::Item(vec![],item.clone()),
(OuterAttrs(ref attrs),StmtItem(ref item)) => StmtKind::Item(attrs.clone(),item.clone()),
(OuterAttrs(ref attrs),Pub,StmtItem(ref item)) => StmtKind::Item(attrs.clone(),item.clone()),
(FullBlockExpr(ref block)) => StmtKind::Block(vec![],block.clone()),
(MaybeOuterAttrs(ref attrs),Block) => StmtKind::Block(attrs.clone(),Rc::new(state.values[1].clone())),
(NonblockExpr(ref expr),Semicolon) => StmtKind::Expr(vec![],expr.clone()),
(OuterAttrs(ref attrs),NonblockExpr(ref expr),Semicolon) => StmtKind::Expr(attrs.clone(),expr.clone()),
(Semicolon) => StmtKind::Empty,
}
nonterminal MaybeExprs(Vec<ExprKind>)
{
(Exprs(ref list)) => list.clone(),
(Exprs(ref list),Comma) => list.clone(),
() => vec![],
}
nonterminal MaybeExpr(Option<ExprKind>)
{
(Expr(ref expr)) => Some(expr.clone()),
() => None,
}
nonterminal Exprs(Vec<ExprKind>)
{
(Expr(ref expr)) => vec![expr.clone()],
(Exprs(ref list),Comma,Expr(ref expr)) =>
{
let mut new=(list.clone());
new.push(expr.clone());
new
},
}
nonterminal PathExpr(PathKind)
{
(PathGenericArgsWithColons(ref path)) => path.clone(),
(ModSep,PathGenericArgsWithColons(ref path)) => PathKind::Absolute(Rc::new(path.clone())),
(LittleSelf,ModSep,PathGenericArgsWithColons(ref path)) => PathKind::FromSelf(Rc::new(path.clone())),
}
// A path with a lifetime and type parameters with double colons before
// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`
//
// These show up in expr context, in order to disambiguate from "less-than"
// expressions.
nonterminal PathGenericArgsWithColons(PathKind)
{
(Ident(ref s)) => PathKind::Ident(s.clone()),
(Super) => PathKind::Super,
(PathGenericArgsWithColons(ref path),ModSep,Ident(ref s)) => PathKind::StepIdent(Rc::new(path.clone()),s.clone()),
(PathGenericArgsWithColons(ref path),ModSep,Super) => PathKind::StepSuper(Rc::new(path.clone())),
(PathGenericArgsWithColons(ref path),ModSep,GenericArgs(ref ga)) => PathKind::GenericArgs(Rc::new(path.clone()),ga.clone()),
}
// the braces-delimited macro is a block_expr so it doesn't appear here
nonterminal MacroExpr(Rc<Token>,Option<Rc<Token>>,Rc<Token>)
{
(PathExpr(ref s),Bang,MaybeIdent,ParensDelimitedTokenTrees(ref trees)) => (Rc::new(Token::PathExpr(s.clone())),None,Rc::new(Token::ParensDelimitedTokenTrees(trees.clone()))),
(PathExpr(ref s),Bang,MaybeIdent,BracketsDelimitedTokenTrees(ref trees)) => (Rc::new(Token::PathExpr(s.clone())),None,Rc::new(Token::BracketsDelimitedTokenTrees(trees.clone()))),
}
nonterminal NonblockExpr(ExprKind)
{
(Lit) => ExprKind::Single(Rc::new(state.values[0].clone())),
(PathExpr) => ExprKind::Single(Rc::new(state.values[0].clone())),
(LittleSelf) => ExprKind::Single(Rc::new(state.values[0].clone())),
(MacroExpr) => ExprKind::Single(Rc::new(state.values[0].clone())),
(PathExpr(ref path),LBrace,StructExprFields(ref fields),RBrace) => ExprKind::Struct(path.clone(),fields.clone()),
(NonblockExpr,QuestionMark) => ExprKind::Fixme,
#[priority(member)]
(NonblockExpr(ref kind),Dot,PathGenericArgsWithColons(ref path)) => ExprKind::Member(Rc::new(kind.clone()),path.clone()),
(NonblockExpr,Dot,LitInteger) => ExprKind::Fixme,
(NonblockExpr(ref kind),LBracket,MaybeExpr(ref option),RBracket) => match option
{
&None => ExprKind::Index(Rc::new(kind.clone()),None),
&Some(ref qindex) => ExprKind::Index(Rc::new(kind.clone()),Some(Rc::new(qindex.clone()))),
},
(NonblockExpr(ref kind),LPar,MaybeExprs(ref arguments),RPar) => ExprKind::Call(Rc::new(kind.clone()),arguments.clone()),
(LBracket,VecExpr,RBracket) => ExprKind::Fixme,
(LPar,MaybeExprs(ref arguments),RPar) => ExprKind::Parentheses(arguments.clone()),
(Continue) => ExprKind::Fixme,
(Continue,Lifetime) => ExprKind::Fixme,
(Return) => ExprKind::Return(None),
(Return,Expr(ref expr)) => ExprKind::Return(Some(Rc::new(expr.clone()))),
(Break) => ExprKind::Break(None),
(Break,Lifetime(ref lifetime)) => ExprKind::Break(Some(lifetime.clone())),
(Yield) => ExprKind::Fixme,
(Yield,Expr) => ExprKind::Fixme,
(NonblockExpr,LArrow,Expr) => ExprKind::Fixme,
#[priority(qassignation)]
(NonblockExpr(ref left),Equal,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(NonblockExpr,SHLEQ,Expr) => (),
(NonblockExpr(ref left),LT,NoSpace,LT,Equal,Expr(ref right)) => ExprKind::Fixme,
//(NonblockExpr,SHREQ,Expr) => (),
(NonblockExpr(ref left),GT,NoSpace,GT,Equal,Expr(ref right)) => ExprKind::Fixme,
(NonblockExpr(ref left),MinusEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),AndEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),OrEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),PlusEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),StarEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),SlashEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),CaretEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),PercentEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),OrOr,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),AndAnd,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),EqualEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),NE,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),LT,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),GT,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),LE,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),GE,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),Vertical,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),Caret,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),Ampersand,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(NonblockExpr,SHL,Expr) => (),
(NonblockExpr(ref left),LT,NoSpace,LT,Expr(ref right)) => ExprKind::Fixme,
//(NonblockExpr,SHR,Expr) => (),
(NonblockExpr(ref left),GT,NoSpace,GT,Expr(ref right)) => ExprKind::Fixme,
(NonblockExpr(ref left),Plus,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),Minus,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),Star,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),Slash,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),Percent,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(NonblockExpr(ref left),DotDot) => ExprKind::Range(Some(Rc::new(left.clone())),None),
(NonblockExpr(ref left),DotDot,Expr(ref right)) => ExprKind::Range(Some(Rc::new(left.clone())),Some(Rc::new(right.clone()))),
(DotDot,Expr(ref right)) => ExprKind::Range(None,Some(Rc::new(right.clone()))),
(DotDot) => ExprKind::Range(None,None),
(NonblockExpr,As,Ty) => ExprKind::Fixme,
(NonblockExpr,Colon,Ty) => ExprKind::Fixme,
(BOX,Expr) => ExprKind::Fixme,
(ExprQualifiedPath) => ExprKind::Fixme,
(NonblockPrefixExpr(ref expr)) => expr.clone(),
}
nonterminal Expr(ExprKind)
{
(Lit) => ExprKind::Single(Rc::new(state.values[0].clone())),
(PathExpr) => ExprKind::Single(Rc::new(state.values[0].clone())),
(LittleSelf) => ExprKind::Single(Rc::new(state.values[0].clone())),
(MacroExpr) => ExprKind::Single(Rc::new(state.values[0].clone())),
(PathExpr(ref path),LBrace,StructExprFields(ref fields),RBrace) => ExprKind::Struct(path.clone(),fields.clone()),
(Expr,QuestionMark) => ExprKind::Fixme,
#[priority(member)]
(Expr(ref kind),Dot,PathGenericArgsWithColons(ref string)) => ExprKind::Member(Rc::new(kind.clone()),string.clone()),
(Expr,Dot,LitInteger) => ExprKind::Fixme,
(Expr(ref kind),LBracket,MaybeExpr(ref option),RBracket) => match option
{
&None => ExprKind::Index(Rc::new(kind.clone()),None),
&Some(ref qindex) => ExprKind::Index(Rc::new(kind.clone()),Some(Rc::new(qindex.clone()))),
},
(Expr(ref kind),LPar,MaybeExprs(ref arguments),RPar) => ExprKind::Call(Rc::new(kind.clone()),arguments.clone()),
(LPar,MaybeExprs(ref arguments),RPar) => ExprKind::Parentheses(arguments.clone()),
(LBracket,VecExpr,RBracket) => ExprKind::Fixme,
(Continue) => ExprKind::Fixme,
(Continue,Ident) => ExprKind::Fixme,
(Return) => ExprKind::Return(None),
(Return,Expr(ref expr)) => ExprKind::Return(Some(Rc::new(expr.clone()))),
(Break) => ExprKind::Break(None),
(Break,Ident(ref string)) => ExprKind::Break(Some(string.clone())),
(Yield) => ExprKind::Fixme,
(Yield,Expr) => ExprKind::Fixme,
(Expr,LArrow,Expr) => ExprKind::Fixme,
#[priority(qassignation)]
(Expr(ref left),Equal,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(Expr,SHLEQ,Expr) => (),
(Expr(ref left),LT,NoSpace,LT,Equal,Expr(ref right)) => ExprKind::Fixme,
//(Expr,SHREQ,Expr) => (),
(Expr(ref left),GT,NoSpace,GT,Equal,Expr(ref right)) => ExprKind::Fixme,
(Expr(ref left),MinusEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),AndEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),OrEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),PlusEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),StarEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),SlashEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),CaretEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),PercentEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),OrOr,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),AndAnd,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),EqualEqual,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),NE,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),LT,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),GT,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),LE,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),GE,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Vertical,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Caret,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Ampersand,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(Expr,SHL,Expr) => (),
(Expr(ref left),LT,NoSpace,LT,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(Expr,SHR,Expr) => (),
(Expr(ref left),GT,NoSpace,GT,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Plus,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Minus,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Star,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Slash,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),Percent,Expr(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(Expr(ref left),DotDot) => ExprKind::Range(Some(Rc::new(left.clone())),None),
(Expr(ref left),DotDot,Expr(ref right)) => ExprKind::Range(Some(Rc::new(left.clone())),Some(Rc::new(right.clone()))),
(DotDot,Expr(ref right)) => ExprKind::Range(None,Some(Rc::new(right.clone()))),
(DotDot) => ExprKind::Range(None,None),
(Expr,As,Ty) => ExprKind::Fixme,
(Expr,Colon,Ty) => ExprKind::Fixme,
(BOX,Expr) => ExprKind::Fixme,
(ExprQualifiedPath) => ExprKind::Fixme,
(BlockExpr(ref block)) => ExprKind::Single(block.clone()),
(Block) => ExprKind::Single(Rc::new(state.values[0].clone())),
(NonblockPrefixExpr(ref expr)) => expr.clone(),
}
nonterminal ExprNostruct(ExprKind)
{
(Lit) => ExprKind::Single(Rc::new(state.values[0].clone())),
(PathExpr) => ExprKind::Single(Rc::new(state.values[0].clone())),
(LittleSelf) => ExprKind::Single(Rc::new(state.values[0].clone())),
(MacroExpr) => ExprKind::Single(Rc::new(state.values[0].clone())),
(ExprNostruct,QuestionMark) => ExprKind::Fixme,
#[priority(member)]
(ExprNostruct(ref kind),Dot,PathGenericArgsWithColons(ref path)) => ExprKind::Member(Rc::new(kind.clone()),path.clone()),
(ExprNostruct,Dot,LitInteger) => ExprKind::Fixme,
(ExprNostruct(ref kind),LBracket,MaybeExpr(ref option),RBracket) => match option
{
&None => ExprKind::Index(Rc::new(kind.clone()),None),
&Some(ref qindex) => ExprKind::Index(Rc::new(kind.clone()),Some(Rc::new(qindex.clone()))),
},
(ExprNostruct(ref kind),LPar,MaybeExprs(ref arguments),RPar) => ExprKind::Call(Rc::new(kind.clone()),arguments.clone()),
(LBracket,VecExpr,RBracket) => ExprKind::Fixme,
(LPar,MaybeExprs(ref arguments),RPar) => ExprKind::Parentheses(arguments.clone()),
(Continue) => ExprKind::Fixme,
(Continue,Ident) => ExprKind::Fixme,
(Return) => ExprKind::Return(None),
(Return,Expr(ref expr)) => ExprKind::Return(Some(Rc::new(expr.clone()))),
(Break) => ExprKind::Break(None),
(Break,Ident(ref string)) => ExprKind::Break(Some(string.clone())),
(Yield) => ExprKind::Fixme,
(Yield,Expr) => ExprKind::Fixme,
(ExprNostruct(ref left),LArrow,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
#[priority(qassignation)]
(ExprNostruct(ref left),Equal,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(ExprNostruct(ref left),SHLEQ,ExprNostruct(ref right)) => (),
(ExprNostruct(ref left),LT,NoSpace,LT,Equal,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),//FIXME
//(ExprNostruct(ref left),SHREQ,ExprNostruct) => (),
(ExprNostruct(ref left),GT,NoSpace,GT,Equal,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),//FIXME
(ExprNostruct(ref left),MinusEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),AndEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),OrEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),PlusEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),StarEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),SlashEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),CaretEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),PercentEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),OrOr,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),AndAnd,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),EqualEqual,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),NE,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),LT,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),GT,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),LE,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),GE,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Vertical,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Caret,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Ampersand,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(ExprNostruct,SHL,ExprNostruct) => (),
(ExprNostruct(ref left),LT,NoSpace,LT,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
//(ExprNostruct,SHR,ExprNostruct) => (),
(ExprNostruct(ref left),GT,NoSpace,GT,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Plus,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Minus,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Star,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Slash,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),Percent,ExprNostruct(ref right)) => ExprKind::Infix(Rc::new(left.clone()),Rc::new(state.values[1].clone()),Rc::new(right.clone())),
(ExprNostruct(ref left),DotDot) => ExprKind::Range(Some(Rc::new(left.clone())),None),
(ExprNostruct(ref left),DotDot,ExprNostruct(ref right)) => ExprKind::Range(Some(Rc::new(left.clone())),Some(Rc::new(right.clone()))),
(DotDot,ExprNostruct(ref right)) => ExprKind::Range(None,Some(Rc::new(right.clone()))),
(DotDot) => ExprKind::Range(None,None),
(ExprNostruct,As,Ty) => ExprKind::Fixme,
(ExprNostruct,Colon,Ty) => ExprKind::Fixme,
(BOX,ExprNostruct) => ExprKind::Fixme,
(ExprQualifiedPath) => ExprKind::Fixme,
(BlockExpr) => ExprKind::Fixme,
(Block) => ExprKind::Fixme,
(NonblockPrefixExprNostruct(ref expr)) => expr.clone(),
}
nonterminal NonblockPrefixExprNostruct(ExprKind)
{
(Minus,ExprNostruct(ref expr)) => ExprKind::Prefix(Rc::new(state.values[0].clone()),Rc::new(expr.clone())),
(Bang,ExprNostruct(ref expr)) => ExprKind::Prefix(Rc::new(state.values[0].clone()),Rc::new(expr.clone())),
(Star,ExprNostruct(ref expr)) => ExprKind::Prefix(Rc::new(state.values[0].clone()),Rc::new(expr.clone())),
(Ampersand,MaybeMut(ismut),ExprNostruct(ref expr)) => if ismut {ExprKind::RefMut(Rc::new(expr.clone()))} else {ExprKind::Ref(Rc::new(expr.clone()))},
(AndAnd,MaybeMut,ExprNostruct) => ExprKind::Fixme,
(LambdaExprNostruct(ref expr)) => expr.clone(),
(Move,LambdaExprNostruct(ref expr)) => expr.clone(),//FIXME
}
nonterminal NonblockPrefixExpr(ExprKind)
{
(Minus,Expr(ref expr)) => ExprKind::Prefix(Rc::new(state.values[0].clone()),Rc::new(expr.clone())),
(Bang,Expr(ref expr)) => ExprKind::Prefix(Rc::new(state.values[0].clone()),Rc::new(expr.clone())),
(Star,Expr(ref expr)) => ExprKind::Prefix(Rc::new(state.values[0].clone()),Rc::new(expr.clone())),
(Ampersand,MaybeMut(ismut),Expr(ref expr)) => if ismut {ExprKind::RefMut(Rc::new(expr.clone()))} else {ExprKind::Ref(Rc::new(expr.clone()))},
(AndAnd,MaybeMut,Expr(ref expr)) => ExprKind::Fixme,
(LambdaExpr(ref expr)) => expr.clone(),
(Move,LambdaExpr(ref expr)) => expr.clone(),//FIXME
}
nonterminal ExprQualifiedPath
{
(LT,TySum,MaybeAsTraitRef,GT,ModSep,Ident,MaybeQPathParams) => (),
//(SHL,TySum,MaybeAsTraitRef,GT,ModSep,Ident,MaybeAsTraitRef,GT,ModSep,Ident) => (),
//(SHL,TySum,MaybeAsTraitRef,GT,ModSep,Ident,GenericArgs,MaybeAsTraitRef,GT,ModSep,Ident) => (),
//(SHL,TySum,MaybeAsTraitRef,GT,ModSep,Ident,MaybeAsTraitRef,GT,ModSep,Ident,GenericArgs) => (),
//(SHL,TySum,MaybeAsTraitRef,GT,ModSep,Ident,GenericArgs,MaybeAsTraitRef,GT,ModSep,Ident,GenericArgs) => (),
}
nonterminal MaybeQPathParams
{
(ModSep,GenericArgs) => (),
() => (),
}
nonterminal MaybeAsTraitRef
{
(As,TraitRef) => (),
() => (),
}
nonterminal LambdaExpr(ExprKind)
{
(OrOr,RetTy(ref ot),Expr(ref expr)) => ExprKind::Lambda(vec![],ot.clone(),Rc::new(expr.clone())),
(Vertical,Vertical,RetTy(ref ot),Expr(ref expr)) => ExprKind::Lambda(vec![],ot.clone(),Rc::new(expr.clone())),
(Vertical,InferrableParams(ref params),Vertical,RetTy(ref ot),Expr(ref expr)) => ExprKind::Lambda(params.clone(),ot.clone(),Rc::new(expr.clone())),
(Vertical,InferrableParams(ref params),OrOr,LambdaExprNoFirstBar(ref expr)) => ExprKind::Lambda(params.clone(),None,Rc::new(expr.clone())),
}
nonterminal LambdaExprNoFirstBar(ExprKind)
{
(Vertical,RetTy(ref ot),Expr(ref expr)) => ExprKind::Lambda(vec![],ot.clone(),Rc::new(expr.clone())),
(InferrableParams(ref params),Vertical,RetTy(ref ot),Expr(ref expr)) => ExprKind::Lambda(params.clone(),ot.clone(),Rc::new(expr.clone())),
(InferrableParams(ref params),OrOr,LambdaExprNoFirstBar(ref expr)) => ExprKind::Lambda(params.clone(),None,Rc::new(expr.clone())),
}
nonterminal LambdaExprNostruct(ExprKind)
{
(OrOr,ExprNostruct(ref expr)) => ExprKind::Lambda(vec![],None,Rc::new(expr.clone())),
(Vertical,Vertical,RetTy(ref ot),ExprNostruct(ref expr)) => ExprKind::Lambda(vec![],ot.clone(),Rc::new(expr.clone())),
(Vertical,InferrableParams(ref params),Vertical,ExprNostruct(ref expr)) => ExprKind::Lambda(params.clone(),None,Rc::new(expr.clone())), //XXX No RetTy?
(Vertical,InferrableParams(ref params),OrOr,LambdaExprNostructNoFirstBar(ref expr)) => ExprKind::Lambda(params.clone(),None,Rc::new(expr.clone())),
}
nonterminal LambdaExprNostructNoFirstBar(ExprKind)
{
(Vertical,RetTy(ref ot),ExprNostruct(ref expr)) => ExprKind::Lambda(vec![],ot.clone(),Rc::new(expr.clone())),
(InferrableParams(ref params),Vertical,RetTy(ref ot),ExprNostruct(ref expr)) => ExprKind::Lambda(params.clone(),ot.clone(),Rc::new(expr.clone())),
(InferrableParams(ref params),OrOr,LambdaExprNostructNoFirstBar(ref expr)) => ExprKind::Lambda(params.clone(),None,Rc::new(expr.clone())),
}
nonterminal VecExpr
{
(MaybeExprs) => (),
(Exprs,Semicolon,Expr) => (),
}
nonterminal StructExprFields(Vec<(String,Option<ExprKind>)>)
{
(FieldInits(ref list)) => list.clone(),
(FieldInits(ref list),Comma) => list.clone(),
(MaybeFieldInits(ref list),DefaultFieldInit) => list.clone(),//FIXME
() => vec![],
}
nonterminal MaybeFieldInits(Vec<(String,Option<ExprKind>)>)
{
(FieldInits(ref list)) => list.clone(),
(FieldInits(ref list),Comma) => list.clone(),
() => vec![],
}
nonterminal FieldInits(Vec<(String,Option<ExprKind>)>)
{
(FieldInit(ref id, ref oe)) => vec![(id.clone(),oe.clone())],
(FieldInits(ref list),Comma,FieldInit(ref id,ref oe)) =>
{
let mut new=(list.clone());
new.push((id.clone(),oe.clone()));
new
},
}
nonterminal FieldInit(String,Option<ExprKind>)
{
(Ident(ref id)) => (id.clone(),None),
(Ident(ref id),Colon,Expr(ref expr)) => (id.clone(),Some(expr.clone())),
(LitInteger(ref number),Colon,Expr(ref expr)) => (number.to_string(),Some(expr.clone())),
}
nonterminal DefaultFieldInit
{
(DotDot,Expr) => (),
}
nonterminal BlockExpr(Rc<Token>)
{
(ExprMatch) => Rc::new(state.values[0].clone()),
(ExprIf) => Rc::new(state.values[0].clone()),
(ExprIfLet) => Rc::new(state.values[0].clone()),
(ExprWhile) => Rc::new(state.values[0].clone()),
(ExprWhileLet) => Rc::new(state.values[0].clone()),
(ExprLoop) => Rc::new(state.values[0].clone()),
(ExprFor) => Rc::new(state.values[0].clone()),
(Unsafe,Block) => Rc::new(state.values[1].clone()),//FIXME
(PathExpr,Bang,MaybeIdent,BracesDelimitedTokenTrees) => Rc::new(state.values[1].clone()),//FIXME
}
nonterminal FullBlockExpr(Rc<Token>)
{
(BlockExpr(ref block)) => block.clone(),
(BlockExprDot) => Rc::new(state.values[0].clone()),//FIXME
}
nonterminal BlockExprDot
{
(BlockExpr,Dot,PathGenericArgsWithColons) => (),
(BlockExprDot,Dot,PathGenericArgsWithColons) => (),
(BlockExpr,Dot,PathGenericArgsWithColons,LBracket,MaybeExpr,RBracket) => (),
(BlockExprDot,Dot,PathGenericArgsWithColons,LBracket,MaybeExpr,RBracket) => (),
(BlockExpr,Dot,PathGenericArgsWithColons,LPar,MaybeExprs,RPar) => (),
(BlockExprDot,Dot,PathGenericArgsWithColons,LPar,MaybeExprs,RPar) => (),
(BlockExpr,Dot,LitInteger) => (),
(BlockExprDot,Dot,LitInteger) => (),
}
nonterminal ExprMatch(ExprKind,Vec<Rc<Token>>)
{
(Match,ExprNostruct(ref expr),LBrace,RBrace) => (expr.clone(),vec![]),
(Match,ExprNostruct(ref expr),LBrace,MatchClauses(ref list),RBrace) => (expr.clone(),list.clone()),
(Match,ExprNostruct(ref expr),LBrace,MatchClauses(ref list),NonblockMatchClause(_,_,_),RBrace) =>
{
let mut new=(list.clone());
new.push(Rc::new(state.values[4].clone()));
(expr.clone(),new)
},
(Match,ExprNostruct(ref expr),LBrace,NonblockMatchClause(_,_,_),RBrace) => (expr.clone(),vec![Rc::new(state.values[3].clone())]),
}
nonterminal MatchClauses(Vec<Rc<Token>>)
{
(MatchClause) => vec![Rc::new(state.values[0].clone())],
(MatchClauses(ref clauses),MatchClause) =>
{
let mut new=(clauses.clone());
new.push(Rc::new(state.values[1].clone()));
new
},
}
nonterminal MatchClause(Vec<AttrKind>,PatKind,Rc<Token>)
{
(NonblockMatchClause(ref attributes, ref pattern, ref expression),Comma) => (attributes.clone(),pattern.clone(),expression.clone()),
(BlockMatchClause(ref attributes, ref pattern, ref expression)) => (attributes.clone(),pattern.clone(),expression.clone()),
(BlockMatchClause(ref attributes, ref pattern, ref expression),Comma) => (attributes.clone(),pattern.clone(),expression.clone()),
}
nonterminal NonblockMatchClause(Vec<AttrKind>,PatKind,Rc<Token>)
{
(MaybeOuterAttrs(ref attributes),PatsOr(ref pattern),MaybeGuard,FatArrow,NonblockExpr) => (attributes.clone(),pattern.clone(),Rc::new(state.values[4].clone())),
(MaybeOuterAttrs(ref attributes),PatsOr(ref pattern),MaybeGuard,FatArrow,BlockExprDot) => (attributes.clone(),pattern.clone(),Rc::new(state.values[4].clone())),
}
nonterminal BlockMatchClause(Vec<AttrKind>,PatKind,Rc<Token>)
{
(MaybeOuterAttrs(ref attributes),PatsOr(ref pattern),MaybeGuard,FatArrow,Block) => (attributes.clone(),pattern.clone(),Rc::new(state.values[4].clone())),
(MaybeOuterAttrs(ref attributes),PatsOr(ref pattern),MaybeGuard,FatArrow,BlockExpr) => (attributes.clone(),pattern.clone(),Rc::new(state.values[4].clone())),
}
nonterminal MaybeGuard
{
(If,ExprNostruct) => (),
() => (),
}
nonterminal ExprIf(ExprKind,Rc<Token>,Option<Rc<Token>>)
{
(If,ExprNostruct(ref expr),Block) => (expr.clone(),Rc::new(state.values[2].clone()),None),
(If,ExprNostruct(ref expr),Block,Else,BlockOrIf(ref token)) => (expr.clone(),Rc::new(state.values[2].clone()),Some(token.clone())),
}
nonterminal ExprIfLet(PatKind,ExprKind,Rc<Token>,Option<Rc<Token>>)
{
(If,LiteralLet,Pat(ref pattern),Equal,ExprNostruct(ref expr),Block) => (pattern.clone(),expr.clone(),Rc::new(state.values[5].clone()),None),
(If,LiteralLet,Pat(ref pattern),Equal,ExprNostruct(ref expr),Block,Else,BlockOrIf(ref token)) => (pattern.clone(),expr.clone(),Rc::new(state.values[5].clone()),Some(token.clone())),
}
nonterminal BlockOrIf(Rc<Token>)
{
(Block) => Rc::new(state.values[0].clone()),
(ExprIf) => Rc::new(state.values[0].clone()),
(ExprIfLet) => Rc::new(state.values[0].clone()),
}
nonterminal ExprWhile(ExprKind,Rc<Token>)
{
(MaybeLabel,While,ExprNostruct(ref expr),Block) => (expr.clone(),Rc::new(state.values[3].clone())),
}
nonterminal ExprWhileLet
{
(MaybeLabel,While,LiteralLet,Pat,Equal,ExprNostruct,Block) => (),
}
nonterminal ExprLoop
{
(MaybeLabel,Loop,Block) => (),
}
nonterminal ExprFor(PatKind,ExprKind,Rc<Token>)
{
(MaybeLabel,For,Pat(ref pattern),In,ExprNostruct(ref expr),Block) => (pattern.clone(),expr.clone(),Rc::new(state.values[5].clone())),
}
nonterminal MaybeLabel
{
(Lifetime,Colon) => (),
() => (),
}
nonterminal Let(StmtKind)
{
(LiteralLet,Pat(ref pattern),MaybeTyAscription(ref option_type),MaybeInitExpr(ref option_expr),Semicolon) => StmtKind::Let(pattern.clone(),option_type.clone(),option_expr.clone()),
}
////////////////////////////////////////////////////////////////////////
// Part 5: Macros and misc. rules
////////////////////////////////////////////////////////////////////////
nonterminal Lit(Rc<Token>)
{
(LitByte) => Rc::new(state.values[0].clone()),
(LitChar) => Rc::new(state.values[0].clone()),
(LitInteger) => Rc::new(state.values[0].clone()),
(LitFloat) => Rc::new(state.values[0].clone()),
(True) => Rc::new(state.values[0].clone()),
(False) => Rc::new(state.values[0].clone()),
(Str) => Rc::new(state.values[0].clone()),
}
nonterminal Str(String)
{
(LitStr(ref string)) => string.clone(),
(LitStrRaw) => String::from("FIXME RAW"),
(LitByteStr) => String::from("FIXME BSTR"),
(LitByteStrRaw) => String::from("FIXME BRAW"),
}
nonterminal MaybeIdent
{
() => (),
(Ident) => (),
}
nonterminal Ident(String)
{
(LiteralIdent(ref s)) => s.clone(),
// Weak keywords that can be used as identifiers
(Catch) => String::from("catch"),
(DEFAULT) => String::from("default"),
(Union) => String::from("union"),
}
nonterminal UnpairedToken(Rc<Token>)
{
//(SHL) => (),
//(SHR) => (),
(LE) => Rc::new(state.values[0].clone()),
(EqualEqual) => Rc::new(state.values[0].clone()),
(NE) => Rc::new(state.values[0].clone()),
(GE) => Rc::new(state.values[0].clone()),
(AndAnd) => Rc::new(state.values[0].clone()),
(OrOr) => Rc::new(state.values[0].clone()),
(LArrow) => Rc::new(state.values[0].clone()),
//(SHLEQ) => (),
//(SHREQ) => (),
(MinusEqual) => Rc::new(state.values[0].clone()),
(AndEqual) => Rc::new(state.values[0].clone()),
(OrEqual) => Rc::new(state.values[0].clone()),
(PlusEqual) => Rc::new(state.values[0].clone()),
(StarEqual) => Rc::new(state.values[0].clone()),
(SlashEqual) => Rc::new(state.values[0].clone()),
(CaretEqual) => Rc::new(state.values[0].clone()),
(PercentEqual) => Rc::new(state.values[0].clone()),
(DotDot) => Rc::new(state.values[0].clone()),
(DotDotDot) => Rc::new(state.values[0].clone()),
(ModSep) => Rc::new(state.values[0].clone()),
(RArrow) => Rc::new(state.values[0].clone()),
(FatArrow) => Rc::new(state.values[0].clone()),
(LitByte) => Rc::new(state.values[0].clone()),
(LitChar) => Rc::new(state.values[0].clone()),
(LitInteger) => Rc::new(state.values[0].clone()),
(LitFloat) => Rc::new(state.values[0].clone()),
(LitStr) => Rc::new(state.values[0].clone()),
(LitStrRaw) => Rc::new(state.values[0].clone()),
(LitByteStr) => Rc::new(state.values[0].clone()),
(LitByteStrRaw) => Rc::new(state.values[0].clone()),
(LiteralIdent) => Rc::new(state.values[0].clone()),
(Underscore) => Rc::new(state.values[0].clone()),
(LiteralLifetime) => Rc::new(state.values[0].clone()),
(LittleSelf) => Rc::new(state.values[0].clone()),
(Static) => Rc::new(state.values[0].clone()),
//(Abstract) => (),
//(AlignOf) => (),
(As) => Rc::new(state.values[0].clone()),
//(Become) => (),
(Break) => Rc::new(state.values[0].clone()),
(Catch) => Rc::new(state.values[0].clone()),
(Crate) => Rc::new(state.values[0].clone()),
(DEFAULT) => Rc::new(state.values[0].clone()),
//(Do) => (),
(Else) => Rc::new(state.values[0].clone()),
(Enum) => Rc::new(state.values[0].clone()),
(Extern) => Rc::new(state.values[0].clone()),
(False) => Rc::new(state.values[0].clone()),
//(Final) => (),
(FN) => Rc::new(state.values[0].clone()),
(For) => Rc::new(state.values[0].clone()),
(If) => Rc::new(state.values[0].clone()),
(Impl) => Rc::new(state.values[0].clone()),
(In) => Rc::new(state.values[0].clone()),
(LiteralLet) => Rc::new(state.values[0].clone()),
(Loop) => Rc::new(state.values[0].clone()),
//(Macro) => (),
(Match) => Rc::new(state.values[0].clone()),
(Mod) => Rc::new(state.values[0].clone()),
(Move) => Rc::new(state.values[0].clone()),
(Mut) => Rc::new(state.values[0].clone()),
//(OffsetOf) => (),
//(Override) => (),
//(Priv) => (),
(Pub) => Rc::new(state.values[0].clone()),
//(Pure) => (),
(Ref) => Rc::new(state.values[0].clone()),
(Return) => Rc::new(state.values[0].clone()),
(Struct) => Rc::new(state.values[0].clone()),
//(Sizeof) => (),
(Super) => Rc::new(state.values[0].clone()),
(True) => Rc::new(state.values[0].clone()),
(Trait) => Rc::new(state.values[0].clone()),
(Type) => Rc::new(state.values[0].clone()),
(Union) => Rc::new(state.values[0].clone()),
(Unsafe) => Rc::new(state.values[0].clone()),
//(Unsized) => (),
(Use) => Rc::new(state.values[0].clone()),
//(Virtual) => (),
(While) => Rc::new(state.values[0].clone()),
(Yield) => Rc::new(state.values[0].clone()),
(Continue) => Rc::new(state.values[0].clone()),
//(Proc) => (),
(BOX) => Rc::new(state.values[0].clone()),
(Const) => Rc::new(state.values[0].clone()),
(Where) => Rc::new(state.values[0].clone()),
(Typeof) => Rc::new(state.values[0].clone()),
(InnerDocComment) => Rc::new(state.values[0].clone()),
(OuterDocComment) => Rc::new(state.values[0].clone()),
(Shebang) => Rc::new(state.values[0].clone()),
(StaticLifetime) => Rc::new(state.values[0].clone()),
(Semicolon) => Rc::new(state.values[0].clone()),
(Comma) => Rc::new(state.values[0].clone()),
(Dot) => Rc::new(state.values[0].clone()),
(At) => Rc::new(state.values[0].clone()),
(NumberSign) => Rc::new(state.values[0].clone()),
//(Tilde) => (),
(Colon) => Rc::new(state.values[0].clone()),
//(Dolar) => (),
(Equal) => Rc::new(state.values[0].clone()),
(QuestionMark) => Rc::new(state.values[0].clone()),
(Bang) => Rc::new(state.values[0].clone()),
(LT) => Rc::new(state.values[0].clone()),
(GT) => Rc::new(state.values[0].clone()),
(Minus) => Rc::new(state.values[0].clone()),
(Ampersand) => Rc::new(state.values[0].clone()),
(Vertical) => Rc::new(state.values[0].clone()),
(Plus) => Rc::new(state.values[0].clone()),
(Star) => Rc::new(state.values[0].clone()),
(Slash) => Rc::new(state.values[0].clone()),
(Caret) => Rc::new(state.values[0].clone()),
(Percent) => Rc::new(state.values[0].clone()),
}
nonterminal TokenTrees(Vec<Rc<Token>>)
{
() => vec![],
(TokenTrees(ref trees),TokenTree(ref token)) =>
{
let mut new=(trees.clone());
new.push(token.clone());
new
},
}
nonterminal TokenTree(Rc<Token>)
{
//(DelimitedTokenTrees(ref trees)) => Rc::new(Token_DelimitedTokenTrees(trees.clone())),
(DelimitedTokenTrees(ref trees)) => trees.clone(),
(UnpairedToken(ref token)) => token.clone(),
}
nonterminal DelimitedTokenTrees(Rc<Token>)
{
(ParensDelimitedTokenTrees(ref trees)) => Rc::new(Token::ParensDelimitedTokenTrees(trees.clone())),
(BracesDelimitedTokenTrees(ref trees)) => Rc::new(Token::BracesDelimitedTokenTrees(trees.clone())),
(BracketsDelimitedTokenTrees(ref trees)) => Rc::new(Token::BracketsDelimitedTokenTrees(trees.clone())),
}
nonterminal ParensDelimitedTokenTrees(Vec<Rc<Token>>)
{
(LPar,TokenTrees(ref trees),RPar) => trees.clone(),
}
nonterminal BracesDelimitedTokenTrees(Vec<Rc<Token>>)
{
(LBrace,TokenTrees(ref trees),RBrace) => trees.clone(),
}
nonterminal BracketsDelimitedTokenTrees(Vec<Rc<Token>>)
{
(LBracket,TokenTrees(ref trees),RBracket) => trees.clone(),
}
nonterminal MaybeSpace
{
(NoSpace) => (),
() => (),
}
//New
nonterminal ItemTerminal(ItemKind)
{
//(Struct,Ident,GenericParams,MaybeWhereClause,StructDeclArgs) => (),
//(Struct,Ident,GenericParams,StructTupleArgs,MaybeWhereClause,Semicolon) => (),
//(MaybeDefaultMaybeUnsafe,Impl,GenericParams,TyPrimSum,MaybeWhereClause,LBrace,MaybeInnerAttrs,MaybeImplItems,RBrace) => (),
(Terminal,Ident(ref id),LBrace,MaybeTerminalItems(ref items),RBrace) => ItemKind::Terminal(id.clone(),None,items.clone()),
(Terminal,Ident(ref id),LPar,MaybeTySums,RPar,LBrace,MaybeTerminalItems(ref items),RBrace) => ItemKind::Terminal(id.clone(),Some(Rc::new(state.values[3].clone())),items.clone()),
}
//New
nonterminal MaybeTerminalItems(Vec<ItemKind>)
{
(TerminalItems(ref items)) => items.clone(),
() => vec![],
}
//New
nonterminal TerminalItems(Vec<ItemKind>)
{
(TerminalItem(ref item)) => vec![item.clone()],
(TerminalItem(ref item),TerminalItems(ref items)) =>
{
let mut new=(vec![item.clone()]);
//new.extend(items.iter().map(|x|x.clone()));
new.extend(items.iter().map( |x|(x.clone()) ));
new
},
}
//New
nonterminal TerminalItem(ItemKind)
{
(ItemFn(ref item)) => item.clone(),
//(AttrsAndVis,ItemMacro) => (),
//(ImplConst) => (),
//(ImplType) => (),
}
//New
nonterminal ItemNonterminal(ItemKind)
{
(Nonterminal,Ident(ref id),LBrace,MatchClauses(ref clauses),RBrace) => ItemKind::Nonterminal(id.clone(),None,clauses.clone()),
(Nonterminal,Ident(ref id),LPar,MaybeTySums,RPar,LBrace,MatchClauses(ref clauses),RBrace) => ItemKind::Nonterminal(id.clone(),Some(Rc::new(state.values[3].clone())),clauses.clone()),
}
ordering!(member,qassignation);
#[derive(Debug)]
struct Rule
{
//left
//right: Vec<usize>,
patterns: Vec<PatKind>,//[Pat(Path(LitOrPath("NoSpace")))] , Pat(Enum(PathExpr("MaybeModItems"), PatTup([Pat(Path(LitOrPath("items")))])))
expression: Rc<Token>,//NonblockExpr
priority: Option<String>
}
#[derive(Debug)]
struct TokenInfo
{
id: String,
//type_arguments: Vec<Rc<Token>>,
type_arguments: Vec<TyLf>,
is_terminal: bool,
re: Option<String>,
fn_match: Option<ItemKind>,
rules: Vec<Rule>
}
struct Compiler<'a>
{
source: &'a Token,
token_info: Vec<TokenInfo>,
first_nonterminal: Option<usize>,
token_name_to_index: HashMap<String,usize>,//already with the +1
ordering: HashMap<(String,String),Ordering>,
ignore_res: Vec<(usize,String)>
}
impl<'a> Compiler<'a>
{
fn process_token(&mut self,token:&Token)
{
//println!(">>process_token {:?}",token);
match token
{
&Token::WholeCrate(ref items) =>
{
for item in items
{
self.process_token(item);
}
},
&Token::ModItem(ref attributes,ref item) =>
{
//self.process_token(item);
match item
{
&ItemKind::Fixme => println!("fixme item={:?}",item),
&ItemKind::Macro(ref path, ref id, ref tree) =>
{
match (path.as_ref(),tree.as_ref())
{
(&Token::PathExpr(PathKind::Ident(ref s)),&Token::ParensDelimitedTokenTrees(ref data)) =>
{
if s=="re_terminal"
{
//println!("re_terminal macro = {:?}",item);
let mut comma_index=0;
while (comma_index<(data.len())) && ((*data[comma_index])!=Token::Comma)
{
comma_index+=1;
}
if comma_index<(data.len())
{
match (data[0].as_ref(),data[comma_index+1].as_ref())
{
(&Token::LiteralIdent(ref id),&Token::LitStr(ref re)) =>
{
let type_arguments=if let &Token::ParensDelimitedTokenTrees(ref data_types)=data[1].as_ref()
{
let mut new=vec![];
for dt in data_types
{
if let &Token::LiteralIdent(ref s)=dt.as_ref()
{
//println!("Got type {}",s);
new.push(TyLf::Type(TyKind::Path(PathWKind::Ident(s.clone()))));
}
else
{
panic!("problem parsing types in macro {:?}",item);
}
}
new
}
else
{
vec![]
};
if id=="_"
{
self.ignore_res.push((self.token_info.len(),re[1..(re.len()-1)].to_string()));
}
else
{
self.token_info.push(TokenInfo{
id:id.clone(),
//type_string:String::from("()"),
type_arguments,
is_terminal: true,
re:Some(re[1..(re.len()-1)].to_string()),
fn_match: None,
rules: vec![],
});
}
},
_ => println!("incorrect data in re_terminal"),
}
}
else
{
println!("incorrect data in re_terminal");
}
}
else if s=="ordering"
{
let mut order=vec![];
for elem in data
{
match elem.as_ref()
{
&Token::LiteralIdent(ref id) => order.push(id.clone()),
&Token::Comma => (),
_ => panic!("incorrect token in ordering! {:?}",elem),
};
}
for i in 0..(order.len())
{
for j in 0..(order.len())
{
self.ordering.insert((order[i].clone(),order[j].clone()),i.cmp(&j));
}
}
}
},
_ => println!("ignoring macro {:?}",token),
};
}
//&ItemKind::FN(ref ) => (),
&ItemKind::Terminal(ref id, ref ty, ref items) =>
{
let type_arguments= match ty
{
&None => vec![],
&Some(ref mts) => match mts.as_ref()
{
&Token::MaybeTySums(ref types) => types.clone(),
_ => panic!(""),
}
};
let mut fn_match=None;
for item in items
{
match item
{
&ItemKind::FN(ref name, ref lifetimes,ref _gp,ref _params,ref _oret,ref _bs,ref _be) =>
{
if name=="_match"
{
fn_match=(Some(item.clone()));
}
else
{
panic!("received fn {} is terminal {}",name,id);
}
},
_ => panic!("We do not know what to do with item {:?} in terminal {}",item,id),
};
}
self.token_info.push(TokenInfo{
id:id.clone(),
//type_string:String::from("()"),
type_arguments,
is_terminal: true,
re: None,
fn_match,
rules: vec![],
});
},
&ItemKind::Nonterminal(ref id, ref ty, ref clauses) =>
{
if let None=self.first_nonterminal
{
self.first_nonterminal=(Some(self.token_info.len()));
}
let mut rules=vec![];
for clause in clauses
{
//println!("Found clause {:?}",clause);
if let &Token::MatchClause(ref attributes,ref patterns,ref expression)=clause.as_ref()
{
let mut rule_patterns =vec![];
if let &PatKind::Tuple(ref patterns)=patterns
{
//rule_patterns.push(pat.clone());
rule_patterns=(patterns.clone());
}
let mut priority=None;
for attr in attributes
{
if let &AttrKind::Sequence(ref attr_name, ref seq)=attr
{
if attr_name=="priority"
{
if seq.len()!=1
{
panic!("there must be exactly one priority flag ({:?})",attr);
}
if let AttrKind::Flag(ref p_flag)=seq[0]
{
priority=(Some(p_flag.clone()));
}
else
{
panic!("I do not understand this priority {:?}",attr);
}
}
}
}
rules.push(Rule{
//right: vec![],
patterns: rule_patterns,
expression: expression.clone(),
priority,
});
}
}
let type_arguments= match ty
{
&None => vec![],
&Some(ref mts) => match mts.as_ref()
{
&Token::MaybeTySums(ref types) => types.clone(),
_ => panic!(""),
}
};
self.token_info.push(TokenInfo{
id:id.clone(),
//type_string:String::from("()"),
type_arguments,
is_terminal: false,
re: None,
fn_match: None,
rules,
});
},
_ =>
{
for attr in attributes
{
println!("{}",attr);
}
println!("{}",item);
},
//&ItemKind::View(ref view) => println!("{}",view),
//&ItemKind::Enum(ref id, ref params, ref defs) =>
//{
// print!("enum {}",id);
// if params.len()>0
// {
// print!("({})",params.join(","));
// }
// println!("{{");
// for &(ref name,ref tys) in defs
// {
// print!("{}",name);
// if tys.len()>0
// {
// print!("({})",tys.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(","))
// }
// println!(",");
// }
// println!("}}");
//},
}
},
//&Token::ItemMacro(ref path, ref id, ref tree) =>
//{
// //println!("Got macro {:?} with data {:?}",path,tree);
// match (path.as_ref(),tree.as_ref())
// {
// (&Token::PathExpr(PathKind::Ident(ref s)),&Token::ParensDelimitedTokenTrees(ref data)) =>
// {
// if s=="re_terminal"
// {
// let mut comma_index=0;
// while comma_index<data.len() && *data[comma_index]!=Token::Comma
// {
// comma_index+=1;
// }
// if comma_index<data.len()
// {
// match (data[0].as_ref(),data[comma_index+1].as_ref())
// {
// (&Token::LiteralIdent(ref id),&Token::LitStr(ref re)) =>
// {
// if id!="_"
// {
// self.token_info.push(TokenInfo{
// id:id.clone(),
// //type_string:String::from("()"),
// type_arguments: vec![],
// is_terminal: true,
// re:Some(re[1..re.len()-1].to_string()),
// fn_match: None,
// rules: vec![],
// });
// }
// },
// _ => println!("incorrect data in re_terminal"),
// }
// }
// else
// {
// println!("incorrect data in re_terminal");
// }
// }
// else if s=="ordering"
// {
// let mut order=vec![];
// for elem in data
// {
// match elem.as_ref()
// {
// &Token::LiteralIdent(ref id) => order.push(id.clone()),
// &Token::Comma => (),
// _ => panic!("incorrect token in ordering! {:?}",elem),
// };
// }
// for i in 0..order.len()
// {
// for j in 0..order.len()
// {
// self.ordering.insert((order[i].clone(),order[j].clone()),i.cmp(&j));
// }
// }
// }
// },
// _ => println!("ignoring macro {:?}",token),
// };
//},
//&Token::ItemTerminal(ref id, ref ty, ref items) =>
//{
// let type_arguments= match ty
// {
// &None => vec![],
// &Some(ref mts) => match mts.as_ref()
// {
// &Token::MaybeTySums(ref types) => types.clone(),
// _ => panic!(""),
// }
// };
// self.token_info.push(TokenInfo{
// id:id.clone(),
// //type_string:String::from("()"),
// type_arguments,
// is_terminal: true,
// re: None,
// fn_match: None,//FIXME
// rules: vec![],
// });
//},
//&Token::ItemNonterminal(ref id, ref ty, ref clauses) =>
//{
// if let None=self.first_nonterminal
// {
// self.first_nonterminal=Some(self.token_info.len());
// }
// let mut rules=vec![];
// for clause in clauses
// {
// //println!("Found clause {:?}",clause);
// if let &Token::MatchClause(ref attributes,ref patterns,ref expression)=clause.as_ref()
// {
// let mut rule_patterns : Vec<Rc<Token>>=vec![];
// if let &PatKind::Tuple(ref tuple)=patterns
// {
// if let &Token::PatTup(ref pats)=tuple.as_ref()
// {
// for pat in pats
// {
// rule_patterns.push(pat.clone());
// }
// }
// }
// let mut priority=None;
// for attr in attributes
// {
// if let &AttrKind::Sequence(ref attr_name, ref seq)=attr
// {
// if attr_name=="priority"
// {
// if seq.len()!=1
// {
// panic!("there must be exactly one priority flag ({:?})",attr);
// }
// if let AttrKind::Flag(ref p_flag)=seq[0]
// {
// priority=Some(p_flag.clone());
// }
// else
// {
// panic!("I do not understand this priority {:?}",attr);
// }
// }
// }
// }
// rules.push(Rule{
// //right: vec![],
// patterns: rule_patterns,
// expression: expression.clone(),
// priority,
// });
// }
// }
// let type_arguments= match ty
// {
// &None => vec![],
// &Some(ref mts) => match mts.as_ref()
// {
// &Token::MaybeTySums(ref types) => types.clone(),
// _ => panic!(""),
// }
// };
// self.token_info.push(TokenInfo{
// id:id.clone(),
// //type_string:String::from("()"),
// type_arguments,
// is_terminal: false,
// re: None,
// fn_match: None,
// rules,
// });
//},
//&Token::ViewItem(ref view) => println!("{}",view),
//&Token::ItemEnum(ref id, ref params, ref defs) =>
//{
// print!("enum {}",id);
// if params.len()>0
// {
// print!("({})",params.join(","));
// }
// println!("{{");
// for &(ref name,ref tys) in defs
// {
// print!("{}",name);
// if tys.len()>0
// {
// print!("({})",tys.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(","))
// }
// println!(",");
// }
// println!("}}");
//},
_ => (),
};
}
fn compile(&mut self)
{
self.process_token(self.source);
for (i,token) in self.token_info.iter().enumerate()
{
//println!("token {}={:?}",i+1,token);
self.token_name_to_index.insert(token.id.clone(),i+1);
}
//println!("first non-terminal={:?}",self.first_nonterminal);
//println!("--------------------------------------");
println!("#[derive(Clone,Debug,PartialEq)]");
println!("enum Token{{DummyStart,");
for token in self.token_info.iter()
{
if token.type_arguments.len()>0
{
print!("{}({}),",token.id,token.type_arguments.iter().map(|t|format!("{}",t)).collect::<Vec<String>>().join(","));
}
else
{
print!("{},",token.id);
}
}
println!("}}\nimpl Default for Token {{ fn default()->Self{{Token::DummyStart}} }}");
println!("struct ParsingTables {{ }}");
println!("impl ParsingTablesTrait<Token> for ParsingTables {{");
println!("fn initial()->usize {{ {} }}",self.first_nonterminal.unwrap()+1);
println!("fn match_some(parser: &mut Parser<Token,Self>) -> Option<(usize,Token)> {{ let source=&parser.source[parser.source_index..];");
let mut ignore_it=self.ignore_res.iter();
let (mut ignore_pos,mut ignore_sre) = if let Some(&(pos,ref sre))=ignore_it.next()
{
(Some(pos),Some(sre.clone()))
}
else
{
(None,None)
};
for (i,token) in self.token_info.iter().enumerate()
{
if ignore_pos==(Some(i))
{
if let Some(sre)=ignore_sre
{
println!("match {{ match parser.re(\"{}\",source) {{ None => None, Some((size,_string)) => Some((size,())) }} }}",sre);
println!("{{ None => (), Some((size,_result)) => return Some((size,Token::DummyStart)), }};");
}
if let Some(&(pos,ref sre))=ignore_it.next()
{
//(Some(pos),Some(sre.clone()))
ignore_pos=(Some(pos));
ignore_sre=(Some(sre.clone()));
}
else
{
//(None,None)
ignore_pos=None;
ignore_sre=None;
};
}
if token.is_terminal
{
if let Some(ref sre)=token.re
{
//println!("PUT HERE THE MATCH WITH {} re={},",token.id,sre);
if token.type_arguments.len()==0
{
println!("match {{ match parser.re(\"{}\",source) {{ None => None, Some((size,_string)) => Some((size,())) }} }}",sre);
println!("{{ None => (), Some((size,_result)) => return Some((size,Token::{})), }};",token.id);
}
else
{
println!("match {{ match parser.re(\"{}\",source) {{ None => None, Some((size,string)) => Some((size,string.parse::<{}>().unwrap() )) }} }}",sre,token.type_arguments.iter().map(|t|t.to_string()).collect::<Vec<String>>().join(","));
println!("{{ None => (), Some((size,result)) => return Some((size,Token::{}(result))), }};",token.id);
}
}
else if let Some(ref fun)=token.fn_match
{
//println!("PUT HERE THE MATCH WITH {},",token.id);
println!("{{ {}",fun);
if token.type_arguments.len()==0
{
println!("match _match(parser,source) {{ None=>(), Some((size,_result)) => return Some((size,Token::{})), }} }};",token.id);
}
else
{
println!("match _match(parser,source) {{ None=>(), Some((size,result)) => return Some((size,Token::{}(result))), }} }};",token.id);//FIXME tuple
}
}
else
{
panic!("terminal token {} has not matching function",token.id);
}
}
}
println!("None }}//match_some");//match_some
println!("fn predict(parser:&mut Parser<Token,Self>,index:usize,state_index:usize,token:usize) {{ match token {{");
let mut irule=1;
for (i,token) in self.token_info.iter().enumerate()
{
if !token.is_terminal
{
println!("{} => {{",i+1);
//println!("PRINT THE RULES OF TOKEN {}",token.id);
for rule in token.rules.iter()
{
println!("parser.sets[index].predict(State{{rule: {} ,left: {} ,right:vec![ {} ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; {} ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),}});",irule,i+1,rule.patterns.iter().map(|p|match p
{
&PatKind::Path(ref path) => match path
{
&PathKind::Ident(ref string) => self.token_name_to_index.get(string).expect(&format!("string {} not found in map",string)).to_string(),
_ => panic!(""),
},
&PatKind::Enum(ref name, _ ) => match name.as_ref()
{
&Token::PathExpr(PathKind::Ident(ref string)) => self.token_name_to_index.get(string).expect(&format!("string {} not found in map",string)).to_string(),
_ => panic!(""),
},
_ => panic!("received {:?}",p),
}).collect::<Vec<String>>().join(","),rule.patterns.len());
irule+=1;
}
println!("}}");
}
}
println!("_ => panic!(\"\"), }} }}//predict");
println!("fn compute_value(state:&mut State<Token>) {{ state.computed_value = match state.rule {{ 0 => state.values[0].clone(),");
//println!("GO THROUGH THE RULES");
let mut irule=1;
for token in self.token_info.iter()
{
for rule in token.rules.iter()
{
let n=token.type_arguments.len();
if rule.patterns.len()==0
{
if n==0
{
println!("{} => Token::{},",irule,token.id);
}
else if n==1
{
println!("{} => Token::{}({}),",irule,token.id,rule.expression);
}
else
{
let v=(0..n).map(|i| format!("x{}",i) ).collect::<Vec<String>>().join(",");
println!("{} => {{ let ({})={}; Token::{}({}) }},",irule,v,rule.expression,token.id,v);
}
}
else
{
let pattern_string=rule.patterns.iter().map(|p|match p
{
&PatKind::Path(ref path) => match path
{
&PathKind::Ident(ref string) =>
{
let index=self.token_name_to_index.get(string).expect(&format!("{} is not a token",string));
let n=self.token_info[*index-1].type_arguments.len();
if n==0
{
format!("&Token::{}",string)
}
else
{
format!("&Token::{}({})",string,(0..n).map(|_|String::from("_")).collect::<Vec<String>>().join(","))
}
},
_ => panic!(""),
},
&PatKind::Enum(ref name, ref tuple) => match name.as_ref()
{
&Token::PathExpr(ref string) => format!("&Token::{}({})",string,tuple.iter().map(|x| format!("{}",x) ).collect::<Vec<String>>().join(",")),
_ => panic!("name={:?} tuple={:?}",name,tuple),
},
_ => panic!("received {:?}",p),
}).collect::<Vec<String>>().join(",");
if rule.patterns.len()==1
{
println!("{} => match &state.values[0] {{",irule);
print!("{}",pattern_string);
}
else
{
println!("{} => match ({}) {{",irule,(0..rule.patterns.len()).map(|i| format!("&state.values[{}]",i) ).collect::<Vec<String>>().join(","));
print!("({})",pattern_string);
}
if n==0
{
//println!("({}) => Token::{},",pattern_string,token.id);
println!(" => Token::{},",token.id);
}
else if n==1
{
//println!("({}) => Token::{}({}),",pattern_string,token.id,rule.expression);
println!(" => Token::{}({}),",token.id,rule.expression);
}
else
{
// We may need to do unpacking if >=2
// https://stackoverflow.com/questions/39878382/unpacking-tuples-into-arguments
// https://github.com/rust-lang/rust/issues/17274
let v=(0..n).map(|i| format!("x{}",i) ).collect::<Vec<String>>().join(",");
println!(" => {{ let ({})={}; Token::{}({}) }},",v,rule.expression,token.id,v);
}
println!("_ => panic!(\"\"), }},");
}
irule+=1;
}
}
println!("_ => panic!(\"\"), }} }}//compute_value");
println!("fn table_terminal(token_index:usize)->bool {{ match token_index {{");
println!("{} => true,",self.token_info.iter().enumerate().filter_map(|(i,t)|if t.is_terminal {Some((i+1).to_string())} else {None}).collect::<Vec<String>>().join("|"));
println!("0|{} => false,",self.token_info.iter().enumerate().filter_map(|(i,t)|if !t.is_terminal {Some((i+1).to_string())} else {None}).collect::<Vec<String>>().join("|"));
println!("_ => panic!(\"table_terminal\"), }} }}//table_terminal");
println!("fn table_priority(a:usize, b:usize) -> Option<Ordering> {{ match (a,b) {{");
//println!("HERE THE PRIORITIES");
let mut irule=1;
for ltoken in self.token_info.iter()
{
for lrule in ltoken.rules.iter()
{
if let Some(ref lorder)=lrule.priority
{
let mut jrule=1;
for rtoken in self.token_info.iter()
{
for rrule in rtoken.rules.iter()
{
if let Some(ref rorder)=rrule.priority
{
//(6,6) => Some(Ordering::Equal),
println!("({},{}) => Some(Ordering::{:?}),",irule,jrule,self.ordering.get(&(lorder.clone(),rorder.clone())).expect("what?"));
}
jrule+=1;
}
}
}
irule+=1;
}
}
println!("_ => None, }} }}//table_priority");
println!("fn table_associativity(rule:usize) -> Option<Associativity> {{ match rule {{");
println!("_ => None, }} }}//table_associativity");
println!("fn to_usize(token:&Token) -> usize {{ match token {{ &Token::DummyStart => 0,");
for (i,token) in self.token_info.iter().enumerate()
{
if token.type_arguments.len()==0
{
println!("&Token::{} => {},",token.id,i+1);
}
else
{
println!("&Token::{}({}) => {},",token.id,(0..token.type_arguments.len()).map(|_|String::from("_")).collect::<Vec<String>>().join(","),i+1);
}
}
println!("}} }}//to_usize");
println!("}}//impl");//impl
}
}
fn main()
{
let args: Vec<String> = env::args().collect();
//println!("{:?}", args);
if args.len()!=2
{
println!("Use:\n\t{} filename",args[0]);
return;
}
let mut f = File::open(&args[1]).expect("file cannot be opened");
let mut contents = String::new();
f.read_to_string(&mut contents).expect("something went wrong reading the file");
//println!("With text:\n{}", contents);
match Parser::<Token,ParsingTables>::parse(&contents,None)
{
Err(x) => println!("error parsing: {:?}",x),
Ok(x) =>
{
//println!("parsed correctly: {:?}",x);
let mut compiler=Compiler{
source: &x,
token_info: vec![],
first_nonterminal: None,
token_name_to_index: HashMap::new(),
ordering: HashMap::new(),
ignore_res: vec![],
};
compiler.compile();
},
};
}