gramatica 0.2.1

A compiler compiler for Rust implementing Earley's parser.
Documentation
extern crate gramatica;
use std::cmp::Ordering;
use gramatica::{Associativity,EarleyKind,State,Parser,ParsingTablesTrait,AmbiguityInfo};
use std::rc::Rc;
#[derive(Clone,Debug,PartialEq)]
struct XMLElement{
name:String,
attrs:Vec<(String,String)>,
contents:Vec<XMLContent>,
}

#[derive(Clone,Debug,PartialEq)]
enum XMLContent{
Element(XMLElement),
Data(String),
}

use std::io::{BufRead,Read};
fn main(){
let stdin=std::io::stdin();
let mut buf=String::new();
stdin.lock().read_to_string(&mut buf);
match Parser::<Token,ParsingTables>::parse(&buf,None) { Err(x) => println!("error parsing: {:?}" , x), Ok(x) => println!("parsed correctly: {:?}" , x), }
;
}

#[derive(Clone,Debug,PartialEq)]
enum Token{DummyStart,
Space(String),Ident(String),LitStr(String),CloseEmpty,BeginClose,Equal,LT,GT,Other(char),Document(XMLElement),Element(XMLElement),EmptyElemTag(String,Vec<(String,String)>),Attributes(Vec<(String,String)>),Attribute(String,String),STag(String,Vec<(String,String)>),ETag(String),Content(Vec<XMLContent>),Contents(Vec<XMLContent>),MaybeSpace,CharData(String),}
impl Default for Token { fn default()->Self{Token::DummyStart} }
struct ParsingTables { }
impl ParsingTablesTrait<Token> for ParsingTables {
fn initial()->usize { 10 }
fn match_some(parser: &mut Parser<Token,Self>) -> Option<(usize,Token)> { let source=&parser.source[parser.source_index..];
match { match parser.re("(\\s|\n)+",source) { None => None, Some((size,string)) => Some((size,string.parse::<String>().unwrap() )) } }
{ None => (), Some((size,result)) => return Some((size,Token::Space(result))), };
match { match parser.re("[a-zA-Z\\x80-\\xff_][a-zA-Z0-9\\x80-\\xff_]*",source) { None => None, Some((size,string)) => Some((size,string.parse::<String>().unwrap() )) } }
{ None => (), Some((size,result)) => return Some((size,Token::Ident(result))), };
{ 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.push('\\');
r.push(c);}, }
;
size += 2;}, Some(c) => {r.push(c);
size += 1;}, }
;}}
ret}

match _match(parser,source) { None=>(), Some((size,result)) => return Some((size,Token::LitStr(result))), } };
match { match parser.re("/>",source) { None => None, Some((size,_string)) => Some((size,())) } }
{ None => (), Some((size,_result)) => return Some((size,Token::CloseEmpty)), };
match { match parser.re("</",source) { None => None, Some((size,_string)) => Some((size,())) } }
{ None => (), Some((size,_result)) => return Some((size,Token::BeginClose)), };
match { match parser.re("=",source) { None => None, Some((size,_string)) => Some((size,())) } }
{ None => (), Some((size,_result)) => return Some((size,Token::Equal)), };
match { match parser.re("<",source) { None => None, Some((size,_string)) => Some((size,())) } }
{ None => (), Some((size,_result)) => return Some((size,Token::LT)), };
match { match parser.re(">",source) { None => None, Some((size,_string)) => Some((size,())) } }
{ None => (), Some((size,_result)) => return Some((size,Token::GT)), };
match { match parser.re(".",source) { None => None, Some((size,string)) => Some((size,string.parse::<char>().unwrap() )) } }
{ None => (), Some((size,result)) => return Some((size,Token::Other(result))), };
None }//match_some
fn predict(parser:&mut Parser<Token,Self>,index:usize,state_index:usize,token:usize) { match token {
10 => {
parser.sets[index].predict(State{rule: 1 ,left: 10 ,right:vec![ 11 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 1 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
11 => {
parser.sets[index].predict(State{rule: 2 ,left: 11 ,right:vec![ 12 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 1 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 3 ,left: 11 ,right:vec![ 15,17,16 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 3 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
12 => {
parser.sets[index].predict(State{rule: 4 ,left: 12 ,right:vec![ 7,2,13,19,4 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 5 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
13 => {
parser.sets[index].predict(State{rule: 5 ,left: 13 ,right:vec![  ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 0 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 6 ,left: 13 ,right:vec![ 13,1,14 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 3 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
14 => {
parser.sets[index].predict(State{rule: 7 ,left: 14 ,right:vec![ 2,6,3 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 3 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
15 => {
parser.sets[index].predict(State{rule: 8 ,left: 15 ,right:vec![ 7,2,13,19,8 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 5 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
16 => {
parser.sets[index].predict(State{rule: 9 ,left: 16 ,right:vec![ 5,2,19,8 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 4 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
17 => {
parser.sets[index].predict(State{rule: 10 ,left: 17 ,right:vec![ 20 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 1 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 11 ,left: 17 ,right:vec![ 20,18 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 2 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
18 => {
parser.sets[index].predict(State{rule: 12 ,left: 18 ,right:vec![  ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 0 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 13 ,left: 18 ,right:vec![ 18,11,20 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 3 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
19 => {
parser.sets[index].predict(State{rule: 14 ,left: 19 ,right:vec![  ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 0 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 15 ,left: 19 ,right:vec![ 1 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 1 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
20 => {
parser.sets[index].predict(State{rule: 16 ,left: 20 ,right:vec![  ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 0 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 17 ,left: 20 ,right:vec![ 20,1 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 2 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 18 ,left: 20 ,right:vec![ 20,2 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 2 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 19 ,left: 20 ,right:vec![ 20,6 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 2 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
parser.sets[index].predict(State{rule: 20 ,left: 20 ,right:vec![ 20,9 ],position:0,original_set:index,kind:EarleyKind::Predict(state_index),values:vec![Token::DummyStart; 2 ],computed_value:Token::DummyStart,ambiguity_info:AmbiguityInfo::default(),});
}
_ => panic!(""), } }//predict
fn compute_value(state:&mut State<Token>) { state.computed_value = match state.rule { 0 => state.values[0].clone(),
1 => match &state.values[0] {
&Token::Element(ref elem) => Token::Document(elem.clone()),
_ => panic!(""), },
2 => match &state.values[0] {
&Token::EmptyElemTag(ref name,ref attrs) => Token::Element(XMLElement{name:name.clone(),
attrs:attrs.clone(),
contents:vec![],}),
_ => panic!(""), },
3 => match (&state.values[0],&state.values[1],&state.values[2]) {
(&Token::STag(ref name,ref attrs),&Token::Content(ref content),&Token::ETag(_)) => Token::Element(XMLElement{name:name.clone(),
attrs:attrs.clone(),
contents:content.clone(),}),
_ => panic!(""), },
4 => match (&state.values[0],&state.values[1],&state.values[2],&state.values[3],&state.values[4]) {
(&Token::LT,&Token::Ident(ref name),&Token::Attributes(ref attrs),&Token::MaybeSpace,&Token::CloseEmpty) => { let (x0,x1)=(name.clone(),attrs.clone()); Token::EmptyElemTag(x0,x1) },
_ => panic!(""), },
5 => Token::Attributes(vec![]),
6 => match (&state.values[0],&state.values[1],&state.values[2]) {
(&Token::Attributes(ref attrs),&Token::Space(_),&Token::Attribute(ref a,ref b)) => Token::Attributes({let mut new=(attrs.clone());
new.push((a.clone(),b.clone())); new}),
_ => panic!(""), },
7 => match (&state.values[0],&state.values[1],&state.values[2]) {
(&Token::Ident(ref a),&Token::Equal,&Token::LitStr(ref b)) => { let (x0,x1)=(a.clone(),b.clone()); Token::Attribute(x0,x1) },
_ => panic!(""), },
8 => match (&state.values[0],&state.values[1],&state.values[2],&state.values[3],&state.values[4]) {
(&Token::LT,&Token::Ident(ref name),&Token::Attributes(ref attrs),&Token::MaybeSpace,&Token::GT) => { let (x0,x1)=(name.clone(),attrs.clone()); Token::STag(x0,x1) },
_ => panic!(""), },
9 => match (&state.values[0],&state.values[1],&state.values[2],&state.values[3]) {
(&Token::BeginClose,&Token::Ident(ref s),&Token::MaybeSpace,&Token::GT) => Token::ETag(s.clone()),
_ => panic!(""), },
10 => match &state.values[0] {
&Token::CharData(ref s) => Token::Content(vec![XMLContent :: Data (s . clone ())]),
_ => panic!(""), },
11 => match (&state.values[0],&state.values[1]) {
(&Token::CharData(ref s),&Token::Contents(ref list)) => Token::Content({let mut new=vec![XMLContent :: Data (s . clone ())];
new.extend(list.iter().map(|x|x.clone())); new}),
_ => panic!(""), },
12 => Token::Contents(vec![]),
13 => match (&state.values[0],&state.values[1],&state.values[2]) {
(&Token::Contents(ref list),&Token::Element(ref elem),&Token::CharData(ref s)) => Token::Contents({let mut new=(list.clone());
new.push(XMLContent::Element(elem.clone()));
if s != "" {new.push(XMLContent::Data(s.clone()));} new}),
_ => panic!(""), },
14 => { (); Token::MaybeSpace },
15 => match &state.values[0] {
&Token::Space(_) => { (); Token::MaybeSpace },
_ => panic!(""), },
16 => Token::CharData(String::new()),
17 => match (&state.values[0],&state.values[1]) {
(&Token::CharData(ref s),&Token::Space(ref o)) => Token::CharData(format!("{}{}" , s , o)),
_ => panic!(""), },
18 => match (&state.values[0],&state.values[1]) {
(&Token::CharData(ref s),&Token::Ident(ref o)) => Token::CharData(format!("{}{}" , s , o)),
_ => panic!(""), },
19 => match (&state.values[0],&state.values[1]) {
(&Token::CharData(ref s),&Token::Equal) => Token::CharData(format!("{}=" , s)),
_ => panic!(""), },
20 => match (&state.values[0],&state.values[1]) {
(&Token::CharData(ref s),&Token::Other(o)) => Token::CharData(format!("{}{}" , s , o)),
_ => panic!(""), },
_ => panic!(""), } }//compute_value
fn table_terminal(token_index:usize)->bool { match token_index {
1|2|3|4|5|6|7|8|9 => true,
0|10|11|12|13|14|15|16|17|18|19|20 => false,
_ => panic!("table_terminal"), } }//table_terminal
fn table_priority(a:usize, b:usize) -> Option<Ordering> { match (a,b) {
_ => None, } }//table_priority
fn table_associativity(rule:usize) -> Option<Associativity> { match rule {
_ => None, } }//table_associativity
fn to_usize(token:&Token) -> usize { match token { &Token::DummyStart => 0,
&Token::Space(_) => 1,
&Token::Ident(_) => 2,
&Token::LitStr(_) => 3,
&Token::CloseEmpty => 4,
&Token::BeginClose => 5,
&Token::Equal => 6,
&Token::LT => 7,
&Token::GT => 8,
&Token::Other(_) => 9,
&Token::Document(_) => 10,
&Token::Element(_) => 11,
&Token::EmptyElemTag(_,_) => 12,
&Token::Attributes(_) => 13,
&Token::Attribute(_,_) => 14,
&Token::STag(_,_) => 15,
&Token::ETag(_) => 16,
&Token::Content(_) => 17,
&Token::Contents(_) => 18,
&Token::MaybeSpace => 19,
&Token::CharData(_) => 20,
} }//to_usize
}//impl