Skip to content
Snippets Groups Projects
Commit b0ed2ea9 authored by Carlos Valencia's avatar Carlos Valencia
Browse files

refactored and better

parent 2362221e
No related branches found
No related tags found
1 merge request!2Indices removed
Showing
with 242 additions and 511 deletions
......@@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "rustec"
version = "0.1.0"
dependencies = [
"byteorder",
]
......@@ -6,3 +6,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
byteorder = "1"
\ No newline at end of file
use std::fmt::Debug;
use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
pub (crate) struct Pure<T: Debug> {
pub a: T
}
impl<T: Copy + Debug> Parser<T> for Pure<T> {
fn parse_fun(&self, index: usize, _ctx: &mut Context) -> Result<(T, usize), String> {
Ok((self.a, index))
}
}
pub (crate) struct Empty<T> {
pub _t: PhantomData<T>
}
// Ideally this would have type None. I had to give it a type for rust to be happy...
impl<T: Debug> Parser<T> for Empty<T> {
fn parse_fun(&self, _index: usize, _ctx: &mut Context) -> Result<(T, usize), String> {
Err("Empty fail".to_string())
}
}
pub (crate) struct Sat {
pub sat_fun: fn(c: char) -> bool
}
impl Parser<char> for Sat {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
if ctx.input.len() == index {
return Err("Out of bounds".to_string());
}
let c = ctx.input[index] as char;
if (self.sat_fun)(c) {
ctx.consumed_input = ctx.consumed_input + 1;
Ok((c, index + 1))
} else {
Err("Didnt match char".to_string())
}
}
}
// If the parser fails after consuming input then it will backtrack and 'undo' what it has done
pub (crate) struct Attempt<T: Copy + Debug, P: Parser<T>> {
pub parser: P,
pub _t: PhantomData<T>
}
impl<T: Copy + Debug, P: Parser<T>> Parser<T> for Attempt<T, P> {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(T, usize), String> {
// Save context in case of failure
let input_before = ctx.consumed_input;
let col_before = ctx.col;
let row_before = ctx.row;
match self.parser.parse_fun(index, ctx) {
Ok((parsed, i)) => Ok((parsed, i)),
Err(e) => {
ctx.consumed_input = input_before;
ctx.row = row_before;
ctx.col = col_before;
Err(e.to_string())
},
}
}
}
// If the first one fails without consuming input, then the second one is atempted
pub (crate) struct Alternative<T: Debug, F:Parser<T>, P:Parser<T>> {
pub parser_first: F,
pub parser_second: P,
pub _t: PhantomData<T>
}
impl<T: Debug, F:Parser<T>, P:Parser<T>> Parser<T> for Alternative<T,F,P> {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(T, usize), String> {
// Save context in case of failure
let input_before = ctx.consumed_input;
let col_before = ctx.col;
let row_before = ctx.row;
let res_parse_first = self.parser_first.parse_fun(index, ctx);
if res_parse_first.is_err() {
ctx.consumed_input = input_before;
ctx.row = row_before;
ctx.col = col_before;
return self.parser_second.parse_fun(index, ctx);
}
res_parse_first
}
}
pub(crate) struct Zip<A: Debug, B: Debug, F: Parser<A>, P: Parser<B>> {
pub parser_first: F,
pub parser_second: P,
pub _a: PhantomData<A>,
pub _b: PhantomData<B>
}
impl<A: Debug, B: Debug, F: Parser<A>, P: Parser<B>> Parser<(A, B)> for Zip<A, B, F, P> {
fn parse_fun<'a>(&'a self, index: usize, ctx: &mut Context) -> Result <((A, B), usize), String> {
match self.parser_first.parse_fun(index, ctx) {
Ok((parsed_first, index_after_first)) => {
let second = self.parser_second.parse_fun(index_after_first, ctx);
match second {
Ok((parsed_second, index_after_second)) => {
Ok(((parsed_first, parsed_second), index_after_second))
},
Err(e) => Err(e)
}
},
Err(e) => Err(e)
}
}
}
pub(crate) struct Map<A: Debug, B: Debug, P: Parser<A>> {
pub map_a_b_fun: fn(a: A) -> B,
pub parser_a : P,
pub _a: PhantomData<A>,
pub _b: PhantomData<B>
}
impl<A: Debug, B: Debug, P: Parser<A>> Parser<B> for Map<A, B, P> {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(B, usize), String> {
match self.parser_a.parse_fun(index, ctx) {
Ok((parsed, new_index)) => {
let fun_res = (&self.map_a_b_fun)(parsed);
Ok((fun_res, new_index))
},
Err(e) => Err(e)
}
}
}
\ No newline at end of file
pub mod whitespace;
\ No newline at end of file
use crate::parser::Parser;
pub mod whitespace;
pub(crate) struct Char {
pub c: char
}
impl Parser<char> for Char {
fn parse_fun(&self, index: usize, ctx: &mut crate::parser::Context) ->Result<(char, usize), String> {
if index >= ctx.size {
return Err("Out of bounds".to_string());
}
let c = ctx.input[index] as char;
if c == self.c {
ctx.consumed_input = ctx.consumed_input + 1;
Ok((c, index + 1))
} else {
Err("Didnt match char".to_string())
}
}
}
\ No newline at end of file
use crate::Parser;
use crate::parser::Context;
use crate::combinators::atomic_combinators::{Sat};
use crate::combinators::primitive_combinators::{Sat};
pub(crate) struct Whitespace;
......
use std::iter::{FromIterator, TakeWhile};
use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
use crate::combinators::atomic_combinators::{Sat, Alternative, Map, Zip};
use crate::combinators::non_atomic_combinators::{Many, Char};
#[derive(Copy, Clone)]
pub(crate) struct Digit;
impl Parser<char> for Digit {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
if ctx.input.len() == index {
return Err("Out of bounds".to_string());
}
let c = ctx.input[index];
if c >= 0x30 && c <= 0x39 {
ctx.consumed_input = ctx.consumed_input + 1;
Ok((c as char, index + 1))
} else {
Err("Didnt match char".to_string())
}
}
}
#[derive(Copy, Clone)]
pub(crate) struct Whole;
impl Parser<char> for Whole {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
if ctx.input.len() == index {
return Err("Out of bounds".to_string());
}
let c = ctx.input[index];
if c >= 0x31 && c <= 0x39 {
ctx.consumed_input = ctx.consumed_input + 1;
Ok((c as char, index + 1))
} else {
Err("Didnt match char".to_string())
}
}
}
pub(crate) struct Int;
impl Parser<String> for Int {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(String, usize), String> {
let s = ctx.input.into_iter().take_while(|&&c| c>= 0x31 && c <= 0x39).take_while(|&&c| c>= 0x30 && c <= 0x39).map(|c| *c as char).collect::<String>();
let size = s.len();
Ok((s, index + size))
}
}
\ No newline at end of file
......@@ -4,16 +4,16 @@ use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
use crate::combinators::atomic_combinators::{Sat, Alternative, Map, Zip};
use crate::combinators::non_atomic_combinators::{Many};
use crate::combinators::primitive_combinators::{Sat, Alternative, Map, Zip};
use crate::combinators::non_primitive_combinators::{Many};
use crate::combinators::common::characters::{Char};
pub(crate) struct Zero;
impl Parser<char> for Zero {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '0'}
}.parse_fun(index, ctx)
Char {c: '0'}.parse_fun(index, ctx)
}
}
......@@ -21,9 +21,7 @@ pub(crate) struct One;
impl Parser<char> for One {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '1'}
}.parse_fun(index, ctx)
Char {c: '1'}.parse_fun(index, ctx)
}
}
......@@ -31,20 +29,14 @@ pub(crate) struct Two;
impl Parser<char> for Two {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '2'}
}.parse_fun(index, ctx)
Char {c: '2'}.parse_fun(index, ctx)
}
}
pub(crate) struct Three;
impl Parser<char> for Three {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '3'}
}.parse_fun(index, ctx)
Char {c: '3'}.parse_fun(index, ctx)
}
}
......@@ -52,9 +44,7 @@ pub(crate) struct Four;
impl Parser<char> for Four {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '4'}
}.parse_fun(index, ctx)
Char {c: '4'}.parse_fun(index, ctx)
}
}
......@@ -64,10 +54,7 @@ pub(crate) struct Five;
impl Parser<char> for Five {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '5'}
}.parse_fun(index, ctx)
Char {c: '5'}.parse_fun(index, ctx)
}
}
......@@ -77,10 +64,7 @@ pub(crate) struct Six;
impl Parser<char> for Six {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '6'}
}.parse_fun(index, ctx)
Char {c: '6'}.parse_fun(index, ctx)
}
}
......@@ -90,9 +74,7 @@ pub(crate) struct Seven;
impl Parser<char> for Seven {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '7'}
}.parse_fun(index, ctx)
Char {c: '7'}.parse_fun(index, ctx)
}
}
......@@ -101,9 +83,7 @@ pub(crate) struct Eight;
impl Parser<char> for Eight {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '8'}
}.parse_fun(index, ctx)
Char {c: '8'}.parse_fun(index, ctx)
}
}
......@@ -111,12 +91,11 @@ pub(crate) struct Nine;
impl Parser<char> for Nine {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
Sat {
sat_fun: |c| {c == '9'}
}.parse_fun(index, ctx)
Char {c: '9'}.parse_fun(index, ctx)
}
}
pub(crate) struct Whole;
impl Parser<char> for Whole {
......@@ -158,6 +137,7 @@ impl Parser<char> for Whole {
}
}
#[derive(Copy, Clone)]
pub(crate) struct Digit;
impl Parser<char> for Digit {
......
pub mod ints;
use std::iter::{FromIterator, TakeWhile};
use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
pub mod ints_basic;
use crate::combinators::primitive_combinators::{Sat, Alternative, Map, Zip};
use crate::combinators::non_primitive_combinators::{Many};
use crate::combinators::common::characters::Char;
#[derive(Copy, Clone)]
pub(crate) struct Digit;
impl Parser<char> for Digit {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
if ctx.input.len() == index {
return Err("Out of bounds".to_string());
}
let c = ctx.input[index] as u8;
if c >= 0x30 && c <= 0x39 {
ctx.consumed_input = ctx.consumed_input + 1;
Ok((c as char, index + 1))
} else {
Err("Didnt match char".to_string())
}
}
}
#[derive(Copy, Clone)]
pub(crate) struct Whole;
impl Parser<char> for Whole {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(char, usize), String> {
if ctx.input.len() == index {
return Err("Out of bounds".to_string());
}
let c = ctx.input[index] as u8;
if c >= 0x31 && c <= 0x39 {
ctx.consumed_input = ctx.consumed_input + 1;
Ok((c as char, index + 1))
} else {
Err("Didnt match char".to_string())
}
}
}
pub(crate) struct Int;
impl Parser<i32> for Int {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(i32, usize), String> {
let mut zeros = 0;
let mut digits = 0;
let s: i32 = ctx.input.split_at(index).1.iter()
.skip_while(|&&c| {
if c as u8 == 0x30 {
zeros += 1;
return true;
}
return false;
})
.take_while(|&&c| c as u8 >= 0x30 && c as u8 <= 0x39)
.map(|&c| c as i32 - 48)
.fold(0, |acc: i32, c| {
digits += 1;
(acc * 10) + c
});
let size = zeros + digits;
ctx.consumed_input = ctx.consumed_input + size;
Ok((s, index + size))
}
}
\ No newline at end of file
pub mod atomic_combinators;
pub mod non_atomic_combinators;
pub mod primitive_combinators;
pub mod non_primitive_combinators;
pub mod common;
pub mod other;
pub mod tests;
\ No newline at end of file
use std::fmt::Debug;
use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
pub(crate) struct Many<T: Debug, P: Parser<T>> {
pub parser: P,
pub _t: PhantomData<T>
}
impl<T: Debug, P: Parser<T> + Copy> Parser<Vec<T>> for Many<T, P> {
fn parse_fun(&self, index: usize, ctx: &mut Context) -> Result<(Vec<T>, usize), String> {
match self.parser.parse_fun(index, ctx) {
Ok((parsed_first, index_after_parse)) => {
let rec = Many{
parser: self.parser,
_t: PhantomData
}.parse_fun(index_after_parse, ctx);
match rec {
Ok((l, index_after_last_parse)) => {
let mut v = vec![parsed_first];
v.extend(l);
Ok((v, index_after_last_parse))
}
Err(_e) => Ok((vec![parsed_first], index_after_parse))
}
},
Err(_) => Ok((Vec::new(), index))
}
}
}
pub (crate) struct Char {
pub c: char
}
impl Parser<char> for Char {
fn parse_fun(&self, index: usize, ctx: &mut Context) ->Result<(char, usize), String> {
if ctx.input.len() == index {
return Err("Out of bounds".to_string());
}
let c = ctx.input[index] as char;
if self.c == c {
ctx.consumed_input = ctx.consumed_input + 1;
Ok((c, index + 1))
} else {
Err("Didnt match char".to_string())
}
}
}
\ No newline at end of file
......@@ -4,8 +4,8 @@ use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
use crate::combinators::atomic_combinators::{Zip, Map, Alternative, Pure};
use crate::combinators::non_atomic_combinators::{Many};
use crate::combinators::primitive_combinators::{Zip, Map, Alternative, Pure};
use crate::combinators::non_primitive_combinators::{Many};
use super::brainflakes_parser_components::{
Ignore,
......
......@@ -3,7 +3,7 @@ use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
use crate::combinators::atomic_combinators::{Sat, Map};
use crate::combinators::primitive_combinators::{Sat, Map};
#[derive(Clone, Copy)]
pub struct GreaterThan;
......
use std::fmt::Debug;
use std::marker::PhantomData;
use crate::Parser;
use crate::combinators::non_atomic_combinators::Char;
use crate::parser::Context;
use crate::combinators::atomic_combinators::{Sat, Zip, Map, Alternative};
use crate::combinators::common::integers::ints::{Int};
use crate::combinators::common::characters::whitespace::{Whitespace};
// This version of Expression places the resursive part in ()
pub(crate) struct Expr;
pub struct ExprOutput {
left: String,
operator: char,
right: Box<Rest>,
}
#[derive(Debug)]
enum Rest {
I(String),
E(ExprOutput)
}
impl Debug for ExprOutput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} {} {:#?}", self.left, self.operator, self.right)
}
}
impl Parser<ExprOutput> for Expr {
fn parse_fun(&self, index:usize, ctx: &mut Context) -> Result<(ExprOutput, usize), String> {
let parse_left = Zip {
parser_first: Map {
map_a_b_fun: |(num, _w) : (String, char)| num,
parser_a: Zip {
parser_first: Int,
parser_second: Whitespace,
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
parser_second: Map {
map_a_b_fun: |(c, _w): (char, char)| c,
parser_a: Zip {
parser_first: Alternative {
parser_first: Sat {
sat_fun: |c| c == '+'
},
parser_second: Sat {
sat_fun: |c| c == '-'
},
_t: PhantomData
},
parser_second: Whitespace,
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
};
Map {
map_a_b_fun: |((num, c), rest): ((String, char), Rest)| {
ExprOutput{
left: num,
operator: c,
right: Box::new(rest)
}
},
parser_a: Zip {
parser_first: parse_left,
parser_second: Alternative {
parser_first: Map {
map_a_b_fun: |eo| {
Rest::E(eo)},
parser_a: Expr,
_a: PhantomData,
_b: PhantomData
},
parser_second: Map {
map_a_b_fun: |eo| {
Rest::I(eo)
},
parser_a: Int,
_a: PhantomData,
_b: PhantomData
},
_t: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
}.parse_fun(index, ctx)
}
}
pub(crate) struct ExprOpt;
impl Parser<ExprOutput> for ExprOpt {
fn parse_fun(&self, index:usize, ctx: &mut Context) -> Result<(ExprOutput, usize), String> {
let parse_left = Zip {
parser_first: Map {
map_a_b_fun: |(num, _w) : (String, char)| num,
parser_a: Zip {
parser_first: Int,
parser_second: Whitespace,
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
parser_second: Map {
map_a_b_fun: |(c, _w): (char, char)| c,
parser_a: Zip {
parser_first: Alternative {
parser_first: Char {
c: '+'
},
parser_second: Char {
c: '-'
},
_t: PhantomData
},
parser_second: Whitespace,
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
};
Map {
map_a_b_fun: |((num, c), rest): ((String, char), Rest)| {
ExprOutput{
left: num,
operator: c,
right: Box::new(rest)
}
},
parser_a: Zip {
parser_first: parse_left,
parser_second: Alternative {
parser_first: Map {
map_a_b_fun: |eo| {
Rest::E(eo)},
parser_a: Expr,
_a: PhantomData,
_b: PhantomData
},
parser_second: Map {
map_a_b_fun: |eo| {
Rest::I(eo)
},
parser_a: Int,
_a: PhantomData,
_b: PhantomData
},
_t: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
}.parse_fun(index, ctx)
}
}
\ No newline at end of file
pub mod expression;
\ No newline at end of file
use std::fmt::Debug;
use std::marker::PhantomData;
use crate::Parser;
use crate::parser::Context;
use crate::combinators::primitive_combinators::{Sat, Zip, Map, Alternative};
use crate::combinators::non_primitive_combinators::{ThenL, ThenR};
use crate::combinators::common::characters::Char;
use crate::combinators::common::integers::{Int};
use crate::combinators::common::characters::whitespace::{Whitespace};
// // This version of Expression places the resursive part in ()
// pub(crate) struct Expr;
#[derive(Debug, Clone)]
pub enum ExprOutput {
I(i32),
E(Rest)
}
#[derive(Clone, Debug)]
pub struct Rest {
left: i32,
operator: char,
right: Box<ExprOutput>,
}
pub(crate) struct Expr2;
impl Parser<ExprOutput> for Expr2 {
fn parse_fun(&self, index: usize, ctx: &mut Context) ->Result<(ExprOutput, usize), String> {
Alternative {
parser_first: Map {
map_a_b_fun: |((i, operator) , rest) : ((i32, char), ExprOutput)| {
ExprOutput::E(Rest {
left: i,
operator: operator,
right: Box::new(rest)
})},
parser_a: Zip {
parser_first: Zip {
parser_first: Int,
parser_second: ThenR {
parser_first: Whitespace,
parser_second: ThenL {
parser_first: Alternative {
parser_first: Char {c: '+'},
parser_second: Char {c: '-'},
_t: PhantomData
},
parser_second: Whitespace,
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
parser_second: Expr2,
_a: PhantomData,
_b: PhantomData
},
_a: PhantomData,
_b: PhantomData
},
parser_second: Map {
map_a_b_fun: |i: i32| ExprOutput::I(i),
parser_a: Int,
_a: PhantomData,
_b: PhantomData
},
_t: PhantomData
}.parse_fun(index, ctx)
}
}
\ No newline at end of file
use std::marker::PhantomData;
use crate::combinators::atomic_combinators::{Pure, Empty, Sat, Alternative, Map, Zip, Attempt};
use crate::combinators::primitive_combinators::{Pure, Empty, Sat, Alternative, Map, Zip, Attempt};
use crate::parser::{Parser, Context};
#[test]
......@@ -87,7 +87,8 @@ use crate::parser::{Parser, Context};
}
let mut context = Context {
input: "i".as_bytes(),
input: "i".chars().collect(),
size: 1,
consumed_input: 0,
col: 0,
row: 0,
......@@ -137,7 +138,8 @@ use crate::parser::{Parser, Context};
}
let mut context_first = Context {
input: "ix".as_bytes(),
input: "ix".chars().collect(),
size: 2,
consumed_input: 0,
col: 0,
row: 0,
......@@ -160,7 +162,8 @@ use crate::parser::{Parser, Context};
}
let mut context_second = Context {
input: "ex".as_bytes(),
input: "ex".chars().collect(),
size: 2,
consumed_input: 0,
col: 0,
row: 0,
......
......@@ -4,7 +4,9 @@ mod parser;
use parser::{Parser};
mod combinators;
use combinators::common::integers::ints::{Digit, Int};
use combinators::common::integers::{Digit, Int};
use crate::combinators::other::expressions::Expr2;
fn main() {
......@@ -15,8 +17,9 @@ fn main() {
// let res = Expr.parse(_file.as_str());
// println!("{:#?}", res);
let mut count = 0;
let mut count = 1;
let max = 1000000;
// loop {
......@@ -25,13 +28,16 @@ fn main() {
// count += 1
// }
loop {
if count == max {break};
// loop {
// if count == max {break};
// print!("{:#?}", Expr2.parse(format!("{} + 6 + 67", count).as_str()));
// //println!("{}", format!("{}", count).parse::<i32>().unwrap());
print!("{:#?}", Int.parse(format!("{}", count).as_str()));
count += 1
}
// //println!("{:#?}", Int.parse(format!("{}", count).as_str()));
// count += 1
// }
print!("{:#?}", Expr2.parse(format!("0{} - 0009787 + 67 ", 5343).as_str()));
//println!("{:#?}", Digit_opt_more.parse(format!("9").as_str()));
// println!("{:#?}", Expr.parse(format!("221 - {} + 8 + 11077770", 4).as_str()));
......
......@@ -3,8 +3,9 @@ use std::fmt;
#[derive(Debug)]
pub(crate) struct Context<'a> {
pub input: &'a [u8],
pub(crate) struct Context {
pub input: Vec<char>,
pub size: usize,
pub consumed_input: usize,
pub row: usize,
pub col: usize,
......@@ -24,7 +25,7 @@ impl<T: Debug> fmt::Display for Output<T> {
}
}
pub(crate) trait Parser<T: Debug> {
pub(crate) trait Parser<T: Debug + Clone> {
// The parsing function resturns a tuple (Parsed, Rest) or an Error String
fn parse_fun(&self, index: usize, ctx: &mut Context) ->Result<(T, usize), String>;
......@@ -36,7 +37,8 @@ pub(crate) trait Parser<T: Debug> {
}
let mut ctx = Context{
input: input.as_bytes(),
input: input.chars().collect(),
size: input.len(),
consumed_input: 0,
row: 0,
col: 0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment