add parser

This commit is contained in:
collin 2020-06-08 12:24:15 -07:00
parent 08e6eb145c
commit 8846f62c8f
8 changed files with 103 additions and 17 deletions

1
Cargo.lock generated
View File

@ -534,6 +534,7 @@ dependencies = [
"snarkos-errors",
"snarkos-gadgets",
"snarkos-models",
"thiserror",
]
[[package]]

View File

@ -16,4 +16,5 @@ snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" }
from-pest = { version = "0.3.1" }
pest = { version = "2.0" }
pest-ast = { version = "0.3.3" }
pest_derive = { version = "2.0" }
pest_derive = { version = "2.0" }
thiserror = { version = "1.0" }

View File

@ -0,0 +1,5 @@
pub mod parser;
pub use parser::*;
pub mod syntax;
pub use syntax::*;

View File

@ -0,0 +1,22 @@
use crate::{ast::Rule, errors::SyntaxError};
use pest::error::Error;
use std::path::PathBuf;
#[derive(Debug, Error)]
pub enum ParserError {
#[error("Cannot read from the provided file path - {:?}", _0)]
FileReadError(PathBuf),
#[error("{}", _0)]
SyntaxError(#[from] SyntaxError),
#[error("Unable to construct abstract syntax tree")]
SyntaxTreeError,
}
impl From<Error<Rule>> for ParserError {
fn from(error: Error<Rule>) -> Self {
ParserError::SyntaxError(SyntaxError::from(error))
}
}

View File

@ -0,0 +1,29 @@
use crate::ast::Rule;
use pest::error::Error;
#[derive(Debug, Error)]
pub enum SyntaxError {
#[error("aborting due to syntax error")]
Error,
}
impl From<Error<Rule>> for SyntaxError {
fn from(mut error: Error<Rule>) -> Self {
error = error.renamed_rules(|rule| match *rule {
Rule::LINE_END => "`;`".to_owned(),
Rule::type_integer => "`u32`".to_owned(),
Rule::type_field => "`field`".to_owned(),
Rule::type_group => "`group`".to_owned(),
Rule::file => "an import, circuit, or function".to_owned(),
Rule::identifier => "a variable name".to_owned(),
Rule::_type => "a type".to_owned(),
rule => format!("{:?}", rule),
});
println!("{}\n", error);
SyntaxError::Error
}
}

View File

@ -1,8 +1,40 @@
extern crate from_pest;
extern crate pest;
extern crate pest_ast;
#[macro_use]
extern crate pest_derive;
#[macro_use]
extern crate thiserror;
pub mod inputs_ast;
pub mod errors;
pub use errors::*;
//extern crate from_pest;
mod ast;
use from_pest::FromPest;
use std::{fs, path::PathBuf};
pub struct LeoInputsParser;
impl LeoInputsParser {
/// Reads in the given file path into a string.
pub fn load_file(file_path: &PathBuf) -> Result<String, ParserError> {
Ok(fs::read_to_string(file_path)
.map_err(|_| ParserError::FileReadError(file_path.clone()))?)
}
/// Parses the input file and constructs a syntax tree.
pub fn parse_file<'a>(
file_path: &'a PathBuf,
input_file: &'a str,
) -> Result<ast::File<'a>, ParserError> {
// Parse the file using leo.pest
let mut file = ast::parse(input_file)
.map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?;
// Build the abstract syntax tree
let syntax_tree =
ast::File::from_pest(&mut file).map_err(|_| ParserError::SyntaxTreeError)?;
// println!("{:?}", syntax_tree);
Ok(syntax_tree)
}
}

View File

@ -1,17 +1,13 @@
use leo_inputs::{self, inputs_ast};
use leo_inputs::{self, LeoInputsParser};
use from_pest::FromPest;
use std::fs;
use std::env::current_dir;
fn main() {
// Read in file as string
let unparsed_file = fs::read_to_string("input.leo").expect("cannot read file");
let mut path = current_dir().unwrap();
path.push("input.leo");
// Parse the file using leo.pest
let mut file = inputs_ast::parse(&unparsed_file).expect("unsuccessful parse");
let input_file = &LeoInputsParser::load_file(&path).expect("cannot read file");
let syntax_tree = LeoInputsParser::parse_file(&path, input_file).unwrap();
// Build the abstract syntax tree
let syntax_tree = inputs_ast::File::from_pest(&mut file).expect("infallible");
println!("tree: {:?}", syntax_tree);
println!("tree: {:#?}", syntax_tree);
}