#![deny(missing_docs)]
extern crate read_token;
extern crate range;
pub use parse_error_handler::{
stderr_unwrap,
ParseErrorHandler
};
pub use parse_error::ParseError;
pub use meta_rules::{ parse, Rule };
pub type DebugId = usize;
use std::sync::Arc;
use std::fs::File;
use std::path::Path;
use range::Range;
pub mod bootstrap;
pub mod json;
pub mod meta_rules;
pub mod tokenizer;
mod parse_error;
mod parse_error_handler;
mod all {
pub use super::*;
}
#[derive(PartialEq, Clone, Debug)]
pub enum MetaData {
StartNode(Arc<String>),
EndNode(Arc<String>),
Bool(Arc<String>, bool),
F64(Arc<String>, f64),
String(Arc<String>, Arc<String>),
}
#[derive(Clone, Debug, PartialEq)]
pub struct Syntax {
pub rules: Vec<Rule>,
pub names: Vec<Arc<String>>,
}
impl Syntax {
pub fn new() -> Syntax {
Syntax {
rules: vec![],
names: vec![]
}
}
pub fn push(&mut self, name: Arc<String>, rule: Rule) {
self.rules.push(rule);
self.names.push(name);
}
}
pub fn syntax(rules: &str) -> Result<Syntax, (Range, ParseError)> {
match bootstrap::convert(
&try!(parse(&bootstrap::rules(), rules)),
&mut vec![] ) {
Ok(res) => Ok(res),
Err(()) => Err((Range::empty(0), ParseError::Conversion(
format!("Bootstrapping rules are incorrect"))))
}
}
pub fn syntax2(rules: &str) -> Result<Syntax, (Range, ParseError)> {
let new_bootstrap_rules = try!(syntax(include_str!("../assets/better-syntax.txt")));
match bootstrap::convert(
&try!(parse(&new_bootstrap_rules, rules)),
&mut vec![] ) {
Ok(res) => Ok(res),
Err(()) => Err((Range::empty(0), ParseError::Conversion(
format!("Bootstrapping rules are incorrect"))))
}
}
pub fn load_syntax_data<A, B>(
syntax_path: A,
data_path: B
) -> Vec<(Range, MetaData)>
where A: AsRef<Path>, B: AsRef<Path>
{
use std::io::Read;
let mut syntax_file = File::open(syntax_path).unwrap();
let mut s = String::new();
syntax_file.read_to_string(&mut s).unwrap();
let rules = stderr_unwrap(&s, syntax(&s));
let mut data_file = File::open(data_path).unwrap();
let mut d = String::new();
data_file.read_to_string(&mut d).unwrap();
stderr_unwrap(&d, parse(&rules, &d))
}
pub fn load_syntax_data2<A, B>(
syntax_path: A,
data_path: B
) -> Vec<(Range, MetaData)>
where A: AsRef<Path>, B: AsRef<Path>
{
use std::io::Read;
let mut syntax_file = File::open(syntax_path).unwrap();
let mut s = String::new();
syntax_file.read_to_string(&mut s).unwrap();
let rules = stderr_unwrap(&s, syntax2(&s));
let mut data_file = File::open(data_path).unwrap();
let mut d = String::new();
data_file.read_to_string(&mut d).unwrap();
stderr_unwrap(&d, parse(&rules, &d))
}
#[cfg(test)]
mod tests {
use super::*;
fn is_thread_safe<T: Send + Sync>() {}
#[test]
fn meta_data_thread_safe() {
is_thread_safe::<MetaData>();
}
#[test]
fn parse_error_thread_safe() {
is_thread_safe::<ParseError>();
}
#[test]
fn rule_thread_safe() {
is_thread_safe::<Rule>();
}
#[test]
fn syntax_thread_safe() {
is_thread_safe::<Syntax>();
}
}