gramatica 0.2.1

A compiler compiler for Rust implementing Earley's parser.
Documentation

extern crate gramatica;

use std::cmp::Ordering;
use std::io::BufRead;
use gramatica::{Associativity,EarleyKind,State,Parser,ParsingTablesTrait,AmbiguityInfo};

// see https://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html#Infix-Calc


//terminal Num(f64)
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,f64)>
//	{
//		match parser.re("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,string.parse::<f64>().unwrap()),
//		}
//	}
//}
re_terminal!(Num(f64),"[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");

//terminal Plus(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("\\+", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(Plus,"\\+");

//terminal Minus(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("-", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(Minus,"-");

//terminal Star(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("\\*", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(Star,"\\*");

//terminal Slash(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("/", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(Slash,"/");

//terminal Caret(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("\\^", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(Caret,"\\^");

//terminal LPar(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("\\(", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(LPar,"\\(");

//terminal RPar(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("\\)", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(RPar,"\\)");

//terminal NewLine(())
//{
//	fn match(parser: &mut Parser, source:&str) -> Option<(usize,())>
//	{
//		match parser.re("\\n", source)
//		{
//			None => None,
//			Some(size,string) => Some(size,()),
//		}
//	}
//}
re_terminal!(NewLine,"\\n");

re_terminal!(_,"\\s+");//Otherwise skip spaces

#[start_symbol]
nonterminal Input
{
	() => (),
	(Input,Line) => (),
}

nonterminal Line
{
	(NewLine) => (),
	(Expression(value), NewLine) =>
	{
		println!("{}",value);
	},
}

nonterminal Expression(f64)
{
	(Num(value)) => value,
	//#[priority(addition),associativity(left)]
	#[priority(addition)]
	#[associativity(left)]
	(Expression(l),Plus,Expression(r)) => l+r,
	//#[priority(addition),associativity(left)]
	#[priority(addition)]
	#[associativity(left)]
	(Expression(l),Minus,Expression(r)) => l-r,
	//#[priority(multiplication),associativity(left)]
	#[priority(multiplication)]
	#[associativity(left)]
	(Expression(l),Star,Expression(r)) => l*r,
	//#[priority(multiplication),associativity(left)]
	#[priority(multiplication)]
	#[associativity(left)]
	(Expression(l),Slash,Expression(r)) => l/r,
	//#[priority(addition),associativity(left)]
	#[priority(addition)]
	#[associativity(left)]
	(Minus,Expression(value)) => -value,
	//#[priority(exponentiation),associativity(right)]
	#[priority(exponentiation)]
	#[associativity(right)]
	(Expression(l),Caret,Expression(r)) => l.powf(r),
	(LPar,Expression(value),RPar) => value,
}

ordering!(exponentiation,multiplication,addition);

fn parse_from_stdin()
{
	let stdin=std::io::stdin();
	for rline in stdin.lock().lines()
	{
		let line=rline.unwrap()+"\n";
		println!("line={}",line);
		match Parser::<Token,ParsingTables>::parse(&line,None)
		{
			Err(x) => println!("error parsing: {:?}",x),
			Ok(x) => println!("parsed correctly: {:?}",x),
		};
	}
}

fn main()
{
	//let text="1+2*3^4\n";
	//let text="";
	//let text="1+2+3\n4 * 5 * 6\n";
	//Parser::parse(&text,None);
	parse_from_stdin();
}