mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
Working parser
This commit is contained in:
parent
6c4c621dd9
commit
a143322f53
1123
Cargo.lock
generated
1123
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -10,3 +10,6 @@ lazy_static = "1.3.0"
|
|||||||
pest = "2.0"
|
pest = "2.0"
|
||||||
pest_derive = "2.0"
|
pest_derive = "2.0"
|
||||||
pest-ast = "0.3.3"
|
pest-ast = "0.3.3"
|
||||||
|
|
||||||
|
snarkos-gadgets = { path = "../snarkOS/gadgets" }
|
||||||
|
snarkos-models = { path = "../snarkOS/models" }
|
||||||
|
@ -1 +1,2 @@
|
|||||||
x = 5
|
x = 5 + 3
|
||||||
|
y = x * (x * 2)
|
||||||
|
@ -3,9 +3,6 @@
|
|||||||
|
|
||||||
file = { SOI ~ NEWLINE* ~ statement* ~ NEWLINE* ~ EOI }
|
file = { SOI ~ NEWLINE* ~ statement* ~ NEWLINE* ~ EOI }
|
||||||
|
|
||||||
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
|
||||||
WHITESPACE = _{ " " | "\t" ~ NEWLINE }
|
|
||||||
|
|
||||||
/// Visibility
|
/// Visibility
|
||||||
|
|
||||||
visibility_public = { "public" }
|
visibility_public = { "public" }
|
||||||
@ -38,7 +35,7 @@ operation_mul = { "*" }
|
|||||||
operation_div = { "/" }
|
operation_div = { "/" }
|
||||||
operation_pow = { "**" }
|
operation_pow = { "**" }
|
||||||
|
|
||||||
operation_binary = {
|
operation_binary = _ {
|
||||||
operation_and | operation_or |
|
operation_and | operation_or |
|
||||||
operation_eq | operation_neq |
|
operation_eq | operation_neq |
|
||||||
operation_geq | operation_gt | operation_leq | operation_lt |
|
operation_geq | operation_gt | operation_leq | operation_lt |
|
||||||
@ -73,15 +70,14 @@ variable = @{ ((!protected_name ~ ASCII_ALPHA) | (protected_name ~ (ASCII_ALPHAN
|
|||||||
/// Expressions
|
/// Expressions
|
||||||
|
|
||||||
// Consider structs, conditionals, postfix, primary, inline array, array initializer, and unary
|
// Consider structs, conditionals, postfix, primary, inline array, array initializer, and unary
|
||||||
term = { value | variable | ("(" ~ expression ~ ")") }
|
expression_primitive = { value | variable }
|
||||||
|
expression_not = { operation_pre_not ~ expression_term }
|
||||||
|
expression_term = { expression_primitive | expression_not | ("(" ~ expression ~ ")") }
|
||||||
|
|
||||||
expression_not = { operation_pre_not ~ term }
|
expression = { expression_term ~ (operation_binary ~ expression_term)* }
|
||||||
expression_increment = { term ~ operation_post_increment }
|
|
||||||
expression_decrement = { term ~ operation_post_decrement }
|
|
||||||
|
|
||||||
expression_binary = { term ~ (operation_binary ~ term)* }
|
// expression_increment = { expression ~ operation_post_increment }
|
||||||
|
// expression_decrement = { expression ~ operation_post_decrement }
|
||||||
expression = { expression_not | expression_increment | expression_decrement | expression_binary }
|
|
||||||
|
|
||||||
expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
||||||
|
|
||||||
@ -90,7 +86,13 @@ expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
|||||||
statement_assign = { variable ~ "=" ~ expression }
|
statement_assign = { variable ~ "=" ~ expression }
|
||||||
statement_return = { "return" ~ expression_tuple }
|
statement_return = { "return" ~ expression_tuple }
|
||||||
|
|
||||||
statement = { statement_assign | statement_return }
|
statement = { (statement_return | (statement_assign) ~ NEWLINE) ~ NEWLINE* }
|
||||||
|
|
||||||
|
/// Utilities
|
||||||
|
|
||||||
|
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
||||||
|
WHITESPACE = _{ " " | "\t" ~ NEWLINE }
|
||||||
|
|
||||||
|
|
||||||
// /// Conditionals
|
// /// Conditionals
|
||||||
//
|
//
|
||||||
|
194
src/main.rs
194
src/main.rs
@ -9,7 +9,6 @@ extern crate pest_ast;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
@ -53,7 +52,65 @@ mod ast {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary_expression_rule<'ast>(
|
fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
|
||||||
|
Box::new(match pair.as_rule() {
|
||||||
|
Rule::expression_term => {
|
||||||
|
let clone = pair.clone();
|
||||||
|
let next = clone.into_inner().next().unwrap();
|
||||||
|
match next.as_rule() {
|
||||||
|
Rule::expression_primitive => {
|
||||||
|
let next = next.into_inner().next().unwrap();
|
||||||
|
match next.as_rule() {
|
||||||
|
Rule::value => Expression::Value(
|
||||||
|
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
|
||||||
|
),
|
||||||
|
Rule::variable => Expression::Variable(
|
||||||
|
Variable::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||||
|
),
|
||||||
|
rule => unreachable!("`expression_primitive` should contain one of [`value`, `variable`], found {:#?}", rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rule::expression_not => {
|
||||||
|
let span = next.as_span();
|
||||||
|
let mut inner = next.into_inner();
|
||||||
|
let operation = match inner.next().unwrap().as_rule() {
|
||||||
|
Rule::operation_pre_not => Not::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||||
|
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule)
|
||||||
|
};
|
||||||
|
let expression = parse_term(inner.next().unwrap());
|
||||||
|
Expression::Not(NotExpression { operation, expression, span })
|
||||||
|
},
|
||||||
|
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
||||||
|
|
||||||
|
// Rule::expression_increment => {
|
||||||
|
// let span = next.as_span();
|
||||||
|
// let mut inner = next.into_inner();
|
||||||
|
// let expression = parse_expression_term(inner.next().unwrap());
|
||||||
|
// let operation = match inner.next().unwrap().as_rule() {
|
||||||
|
// Rule::operation_post_increment => Increment::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||||
|
// rule => unreachable!("`expression_increment` should yield `operation_post_increment`, found {:#?}", rule)
|
||||||
|
// };
|
||||||
|
// Expression::Increment(IncrementExpression { operation, expression, span })
|
||||||
|
// },
|
||||||
|
// Rule::expression_decrement => {
|
||||||
|
// let span = next.as_span();
|
||||||
|
// let mut inner = next.into_inner();
|
||||||
|
// let expression = parse_expression_term(inner.next().unwrap());
|
||||||
|
// let operation = match inner.next().unwrap().as_rule() {
|
||||||
|
// Rule::operation_post_decrement => Decrement::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||||
|
// rule => unreachable!("`expression_decrement` should yield `operation_post_decrement`, found {:#?}", rule)
|
||||||
|
// };
|
||||||
|
// Expression::Decrement(DecrementExpression { operation, expression, span })
|
||||||
|
// },
|
||||||
|
|
||||||
|
rule => unreachable!("`term` should contain one of ['value', 'variable', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rule => unreachable!("`parse_expression_term` should be invoked on `Rule::expression_term`, found {:#?}", rule),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binary_expression<'ast>(
|
||||||
lhs: Box<Expression<'ast>>,
|
lhs: Box<Expression<'ast>>,
|
||||||
pair: Pair<'ast, Rule>,
|
pair: Pair<'ast, Rule>,
|
||||||
rhs: Box<Expression<'ast>>,
|
rhs: Box<Expression<'ast>>,
|
||||||
@ -80,57 +137,6 @@ mod ast {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_rule_term(pair: Pair<Rule>) -> Box<Expression> {
|
|
||||||
Box::new(match pair.as_rule() {
|
|
||||||
Rule::term => {
|
|
||||||
let clone = pair.clone();
|
|
||||||
let next = clone.into_inner().next().unwrap();
|
|
||||||
match next.as_rule() {
|
|
||||||
Rule::value => Expression::Value(
|
|
||||||
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
|
|
||||||
),
|
|
||||||
Rule::variable => Expression::Variable(
|
|
||||||
Variable::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
|
||||||
),
|
|
||||||
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
|
||||||
|
|
||||||
Rule::expression_not => {
|
|
||||||
let span = next.as_span();
|
|
||||||
let mut inner = next.into_inner();
|
|
||||||
let operation = match inner.next().unwrap().as_rule() {
|
|
||||||
Rule::operation_pre_not => Not::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
|
||||||
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule)
|
|
||||||
};
|
|
||||||
let expression = parse_rule_term(inner.next().unwrap());
|
|
||||||
Expression::Not(NotExpression { operation, expression, span })
|
|
||||||
},
|
|
||||||
Rule::expression_increment => {
|
|
||||||
let span = next.as_span();
|
|
||||||
let mut inner = next.into_inner();
|
|
||||||
let expression = parse_rule_term(inner.next().unwrap());
|
|
||||||
let operation = match inner.next().unwrap().as_rule() {
|
|
||||||
Rule::operation_post_increment => Increment::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
|
||||||
rule => unreachable!("`expression_increment` should yield `operation_post_increment`, found {:#?}", rule)
|
|
||||||
};
|
|
||||||
Expression::Increment(IncrementExpression { operation, expression, span })
|
|
||||||
},
|
|
||||||
Rule::expression_decrement => {
|
|
||||||
let span = next.as_span();
|
|
||||||
let mut inner = next.into_inner();
|
|
||||||
let expression = parse_rule_term(inner.next().unwrap());
|
|
||||||
let operation = match inner.next().unwrap().as_rule() {
|
|
||||||
Rule::operation_post_decrement => Decrement::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
|
||||||
rule => unreachable!("`expression_decrement` should yield `operation_post_decrement`, found {:#?}", rule)
|
|
||||||
};
|
|
||||||
Expression::Decrement(DecrementExpression { operation, expression, span })
|
|
||||||
},
|
|
||||||
rule => unreachable!("`term` should contain one of ['value', 'variable', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rule => unreachable!("`parse_rule_term` should be invoked on `Rule::term`, found {:#?}", rule),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||||
#[pest_ast(rule(Rule::file))]
|
#[pest_ast(rule(Rule::file))]
|
||||||
pub struct File<'ast> {
|
pub struct File<'ast> {
|
||||||
@ -257,25 +263,25 @@ mod ast {
|
|||||||
pub span: Span<'ast>,
|
pub span: Span<'ast>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
// #[derive(Clone, Debug, FromPest, PartialEq)]
|
||||||
#[pest_ast(rule(Rule::expression_increment))]
|
// #[pest_ast(rule(Rule::expression_increment))]
|
||||||
pub struct IncrementExpression<'ast> {
|
// pub struct IncrementExpression<'ast> {
|
||||||
pub expression: Box<Expression<'ast>>,
|
// pub expression: Box<Expression<'ast>>,
|
||||||
pub operation: Increment<'ast>,
|
// pub operation: Increment<'ast>,
|
||||||
#[pest_ast(outer())]
|
// #[pest_ast(outer())]
|
||||||
pub span: Span<'ast>,
|
// pub span: Span<'ast>,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// #[derive(Clone, Debug, FromPest, PartialEq)]
|
||||||
|
// #[pest_ast(rule(Rule::expression_decrement))]
|
||||||
|
// pub struct DecrementExpression<'ast> {
|
||||||
|
// pub expression: Box<Expression<'ast>>,
|
||||||
|
// pub operation: Decrement<'ast>,
|
||||||
|
// #[pest_ast(outer())]
|
||||||
|
// pub span: Span<'ast>,
|
||||||
|
// }
|
||||||
|
|
||||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
#[pest_ast(rule(Rule::expression_decrement))]
|
|
||||||
pub struct DecrementExpression<'ast> {
|
|
||||||
pub expression: Box<Expression<'ast>>,
|
|
||||||
pub operation: Decrement<'ast>,
|
|
||||||
#[pest_ast(outer())]
|
|
||||||
pub span: Span<'ast>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub struct BinaryExpression<'ast> {
|
pub struct BinaryExpression<'ast> {
|
||||||
pub operation: BinaryOperator,
|
pub operation: BinaryOperator,
|
||||||
pub left: Box<Expression<'ast>>,
|
pub left: Box<Expression<'ast>>,
|
||||||
@ -283,14 +289,15 @@ mod ast {
|
|||||||
pub span: Span<'ast>,
|
pub span: Span<'ast>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Expression<'ast> {
|
pub enum Expression<'ast> {
|
||||||
Value(Value<'ast>),
|
Value(Value<'ast>),
|
||||||
Variable(Variable<'ast>),
|
Variable(Variable<'ast>),
|
||||||
Not(NotExpression<'ast>),
|
Not(NotExpression<'ast>),
|
||||||
Increment(IncrementExpression<'ast>),
|
|
||||||
Decrement(DecrementExpression<'ast>),
|
|
||||||
Binary(BinaryExpression<'ast>),
|
Binary(BinaryExpression<'ast>),
|
||||||
|
|
||||||
|
// Increment(IncrementExpression<'ast>),
|
||||||
|
// Decrement(DecrementExpression<'ast>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> Expression<'ast> {
|
impl<'ast> Expression<'ast> {
|
||||||
@ -308,9 +315,10 @@ mod ast {
|
|||||||
Expression::Value(expression) => &expression.span(),
|
Expression::Value(expression) => &expression.span(),
|
||||||
Expression::Variable(expression) => &expression.span,
|
Expression::Variable(expression) => &expression.span,
|
||||||
Expression::Not(expression) => &expression.span,
|
Expression::Not(expression) => &expression.span,
|
||||||
Expression::Increment(expression) => &expression.span,
|
|
||||||
Expression::Decrement(expression) => &expression.span,
|
|
||||||
Expression::Binary(expression) => &expression.span,
|
Expression::Binary(expression) => &expression.span,
|
||||||
|
|
||||||
|
// Expression::Increment(expression) => &expression.span,
|
||||||
|
// Expression::Decrement(expression) => &expression.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,14 +328,13 @@ mod ast {
|
|||||||
type FatalError = Void;
|
type FatalError = Void;
|
||||||
|
|
||||||
fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result<Self, ConversionError<Void>> {
|
fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result<Self, ConversionError<Void>> {
|
||||||
let mut pairs = pest.clone();
|
let mut clone = pest.clone();
|
||||||
println!("{:?}\n", pairs);
|
let pair = clone.next().ok_or(::from_pest::ConversionError::NoMatch)?;
|
||||||
let pair = pairs.next().ok_or(::from_pest::ConversionError::NoMatch)?;
|
|
||||||
match pair.as_rule() {
|
match pair.as_rule() {
|
||||||
Rule::expression => {
|
Rule::expression => {
|
||||||
// Transfer iterated state to pest.
|
// Transfer iterated state to pest.
|
||||||
*pest = pairs;
|
*pest = clone;
|
||||||
Ok(*PRECEDENCE_CLIMBER.climb(pair.into_inner(), parse_rule_term, binary_expression_rule))
|
Ok(*PRECEDENCE_CLIMBER.climb(pair.into_inner(), parse_term, binary_expression))
|
||||||
}
|
}
|
||||||
_ => Err(ConversionError::NoMatch),
|
_ => Err(ConversionError::NoMatch),
|
||||||
}
|
}
|
||||||
@ -369,12 +376,31 @@ mod ast {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use crate::from_pest::FromPest;
|
use crate::from_pest::FromPest;
|
||||||
|
use snarkos_gadgets::curves::edwards_bls12::FqGadget;
|
||||||
|
use snarkos_models::gadgets::{r1cs::{ConstraintSystem, TestConstraintSystem, Fr}, utilities::{alloc::AllocGadget, boolean::Boolean}};
|
||||||
|
|
||||||
let unparsed_file = fs::read_to_string("simple.program").expect("cannot read file");
|
let unparsed_file = fs::read_to_string("simple.program").expect("cannot read file");
|
||||||
let mut file = LanguageParser::parse(Rule::file, &unparsed_file).expect("unsuccessful parse");
|
let mut file = LanguageParser::parse(Rule::file, &unparsed_file).expect("unsuccessful parse");
|
||||||
let syntax_tree = ast::File::from_pest(&mut file).expect("infallible");
|
let syntax_tree = ast::File::from_pest(&mut file).expect("infallible");
|
||||||
|
|
||||||
println!("{:?}", syntax_tree);
|
for statement in syntax_tree.statement {
|
||||||
|
match statement {
|
||||||
|
ast::Statement::Assign(statement) => {
|
||||||
|
println!("{:#?}", statement);
|
||||||
|
},
|
||||||
|
ast::Statement::Return(statement) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||||
|
|
||||||
|
Boolean::alloc(cs.ns(|| format!("boolean")), || Ok(true));
|
||||||
|
|
||||||
|
|
||||||
|
println!("\n\n number of constraints for input: {}", cs.num_constraints());
|
||||||
|
|
||||||
|
|
||||||
// for token in file.into_inner() {
|
// for token in file.into_inner() {
|
||||||
// match token.as_rule() {
|
// match token.as_rule() {
|
||||||
@ -406,8 +432,8 @@ fn main() {
|
|||||||
// println!("Sum of fields: {}", field_sum);
|
// println!("Sum of fields: {}", field_sum);
|
||||||
// println!("Number of records: {}", record_count);
|
// println!("Number of records: {}", record_count);
|
||||||
|
|
||||||
let successful_parse = LanguageParser::parse(Rule::value, "-273");
|
// let successful_parse = LanguageParser::parse(Rule::value, "-273");
|
||||||
println!("{:?}", successful_parse);
|
// println!("{:?}", successful_parse);
|
||||||
|
|
||||||
// let unsuccessful_parse = CSVParser::parse(Rule::field, "this is not a number");
|
// let unsuccessful_parse = CSVParser::parse(Rule::field, "this is not a number");
|
||||||
// println!("{:?}", unsuccessful_parse);
|
// println!("{:?}", unsuccessful_parse);
|
||||||
|
Loading…
Reference in New Issue
Block a user