mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-18 15:31:32 +03:00
Adds AST JSON generator
This commit is contained in:
parent
47bfd2e096
commit
d3894ff546
@ -4,6 +4,10 @@ version = "0.1.0"
|
|||||||
authors = ["The Aleo Team <hello@aleo.org>"]
|
authors = ["The Aleo Team <hello@aleo.org>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "leo_ast"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
from-pest = { version = "0.3.1" }
|
from-pest = { version = "0.3.1" }
|
||||||
lazy_static = { version = "1.3.0" }
|
lazy_static = { version = "1.3.0" }
|
||||||
|
@ -11,6 +11,9 @@ pub enum ParserError {
|
|||||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||||
FileReadError(PathBuf),
|
FileReadError(PathBuf),
|
||||||
|
|
||||||
|
#[error("{}", _0)]
|
||||||
|
JsonError(#[from] serde_json::error::Error),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
SyntaxError(#[from] SyntaxError),
|
SyntaxError(#[from] SyntaxError),
|
||||||
|
|
||||||
|
@ -32,16 +32,16 @@ use std::{fs, path::PathBuf};
|
|||||||
pub struct LeoParser;
|
pub struct LeoParser;
|
||||||
|
|
||||||
impl LeoParser {
|
impl LeoParser {
|
||||||
/// Reads in the given file path into a string.
|
/// Loads the Leo code as a string from the given file path.
|
||||||
pub fn load_file(file_path: &PathBuf) -> Result<String, ParserError> {
|
pub fn load_file(file_path: &PathBuf) -> Result<String, ParserError> {
|
||||||
Ok(fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.clone()))?)
|
Ok(fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.clone()))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the input file and constructs a syntax tree.
|
/// Parses the Leo program string and constructs an abstract syntax tree.
|
||||||
pub fn parse_file<'a>(file_path: &'a PathBuf, input_file: &'a str) -> Result<files::File<'a>, ParserError> {
|
pub fn parse_file<'a>(file_path: &'a PathBuf, program_string: &'a str) -> Result<files::File<'a>, ParserError> {
|
||||||
// Parse the file using leo.pest
|
// Parse the file using leo.pest
|
||||||
let mut file =
|
let mut file = ast::parse(program_string)
|
||||||
ast::parse(input_file).map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?;
|
.map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?;
|
||||||
|
|
||||||
// Build the abstract syntax tree
|
// Build the abstract syntax tree
|
||||||
let syntax_tree = files::File::from_pest(&mut file).map_err(|_| ParserError::SyntaxTreeError)?;
|
let syntax_tree = files::File::from_pest(&mut file).map_err(|_| ParserError::SyntaxTreeError)?;
|
||||||
@ -50,13 +50,8 @@ impl LeoParser {
|
|||||||
Ok(syntax_tree)
|
Ok(syntax_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes and stores a given syntax tree in the output file.
|
/// Serializes a given abstract syntax tree into a JSON string.
|
||||||
pub fn store_syntax_tree<'a>(syntax_tree: files::File<'a>, output_file: &'a str) -> Result<(), ParserError> {
|
pub fn to_json_string(syntax_tree: &files::File) -> Result<String, ParserError> {
|
||||||
// Serialize and store the syntax tree to the given filepath.
|
Ok(serde_json::to_string_pretty(syntax_tree)?)
|
||||||
let serialized_syntax_tree = serde_json::to_string(&syntax_tree).unwrap();
|
|
||||||
println!("serialized = {}", serialized_syntax_tree);
|
|
||||||
fs::write(output_file, serialized_syntax_tree)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
ast/src/main.rs
Normal file
50
ast/src/main.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use leo_ast::{LeoParser, ParserError};
|
||||||
|
use std::{env, fs, path::Path};
|
||||||
|
|
||||||
|
fn to_leo_ast(filepath: &Path) -> Result<String, ParserError> {
|
||||||
|
// Loads the Leo code as a string from the given file path.
|
||||||
|
let program_filepath = filepath.to_path_buf();
|
||||||
|
let program_string = LeoParser::load_file(&program_filepath)?;
|
||||||
|
|
||||||
|
// Parses the Leo program string and constructs an abstract syntax tree.
|
||||||
|
let abstract_syntax_tree = LeoParser::parse_file(&program_filepath, &program_string)?;
|
||||||
|
|
||||||
|
// Serializes the abstract syntax tree into JSON format.
|
||||||
|
let serialized_ast = LeoParser::to_json_string(&abstract_syntax_tree)?;
|
||||||
|
|
||||||
|
Ok(serialized_ast)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), ParserError> {
|
||||||
|
// Parse the command-line arguments as strings.
|
||||||
|
let cli_arguments = env::args().collect::<Vec<String>>();
|
||||||
|
|
||||||
|
// Check that the correct number of command-line arguments were passed in.
|
||||||
|
if cli_arguments.len() < 2 || cli_arguments.len() > 3 {
|
||||||
|
eprintln!("Error - invalid number of command-line arguments");
|
||||||
|
println!("\nCommand-line usage:\n\n\tleo_ast {{input_filename}}.leo {{optional_output_filepath}}\n");
|
||||||
|
return Ok(()); // Exit innocently
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the input filepath.
|
||||||
|
let input_filepath = Path::new(&cli_arguments[1]);
|
||||||
|
|
||||||
|
// Create the serialized abstract syntax tree.
|
||||||
|
let serialized_ast = to_leo_ast(&input_filepath)?;
|
||||||
|
println!("{}", serialized_ast);
|
||||||
|
|
||||||
|
// Create the output filepath.
|
||||||
|
let output_filepath = match cli_arguments.len() == 3 {
|
||||||
|
true => format!(
|
||||||
|
"{}/{}.json",
|
||||||
|
cli_arguments[2],
|
||||||
|
input_filepath.file_stem().unwrap().to_str().unwrap()
|
||||||
|
),
|
||||||
|
false => format!("./{}.json", input_filepath.file_stem().unwrap().to_str().unwrap()),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Write the serialized abstract syntax tree to the output filepath.
|
||||||
|
fs::write(Path::new(&output_filepath), serialized_ast)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -94,11 +94,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
|||||||
generate_test_constraints::<F, G>(cs, self.program, &self.imported_programs)
|
generate_test_constraints::<F, G>(cs, self.program, &self.imported_programs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads the Leo code as a string from the given file path.
|
||||||
fn load_program(&mut self) -> Result<String, CompilerError> {
|
fn load_program(&mut self) -> Result<String, CompilerError> {
|
||||||
// Load the program syntax tree from the file path
|
|
||||||
Ok(LeoParser::load_file(&self.main_file_path)?)
|
Ok(LeoParser::load_file(&self.main_file_path)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses the Leo program string, constructs a syntax tree, and generates a program.
|
||||||
pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> {
|
pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> {
|
||||||
// Parse the program syntax tree
|
// Parse the program syntax tree
|
||||||
let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?;
|
let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user