#Need some Help with parsing a function

24 messages · Page 1 of 1 (latest)

remote yoke
#

Guys i need some help i spent several days stuck over this it should be really simple it's just that i'm dumb so here i have a parser file called parser.rs in it i have created this function that only parses binary comparisons
pub fn comparison(input: &str) -> IResult<&str, Node> {
let (input, left) = value(input)?;
let (input, _) = many0(tag(" "))(input)?;
let (input, operator) = alt((
tag("=="), tag("!="), tag("<="), tag(">="), tag("<"), tag(">")
))(input)?;
let (input, _) = many0(tag(" "))(input)?;
let (input, right) = value(input)?;
let children = vec![left, right];
let name = match operator {
"==" => "==",
"!=" => "!=",
"<=" => "<=",
">=" => ">=",
"<" => "<",
">" => ">",
_ => return Err(nom::Err::Failure(nom::error::Error::new(input, nom::error::ErrorKind::Tag)))
};
Ok((input, Node::ComparisonExpression { name: name.to_string(), children }))
}
this is what it looks like as you can see it's failing to pass this test test!(invalidComparison2, r#"x + y * z > x * y - z == false"#, Ok(Value::Bool(true)));
giving me this error "
---- invalidComparison2 stdout ----
thread 'invalidComparison2' panicked at 'assertion failed: (left == right)
left: " > x * y - z == false",
right: ""', tests\test.rs:78:1
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

failures:
invalidComparison2

test result: FAILED. 34 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s

error: test failed, to rerun pass --test test" so what i want to know is how can i please make this function handle all type of comparisons and be able to parse them correctly .Thanks in advance

graceful coral
#

What is your test! macro?

remote yoke
#

this is my test.rs file ```extern crate asalang;
extern crate nom;

use asalang::{program, Node, Value, start_interpreter};
use nom::IResult;

macro_rules! test {
($func:ident, $test:tt, $expected:expr) => (
#[test]
fn $func() -> Result<(),String> {
match program($test) {
Ok((input, p)) => {
assert_eq!(input, "");
assert_eq!(start_interpreter(&p), $expected);
Ok(())
},
Err(e) => Err(format!("{:?}",e)),
}
}
)
}
test!(invalidComparison, r#"1 > true"#, Err("Invalid comparison operands"));
test!(invalidComparison2, r#"x + y * z > x * y - z == false"#, Ok(Value::Bool(true)));```

remote yoke
# graceful coral What is your `test!` macro?

my test macro is this macro_rules! test {
($func:ident, $test:tt, $expected:expr) => (
#[test]
fn $func() -> Result<(),String> {
match program($test) {
Ok((input, p)) => {
assert_eq!(input, "");
assert_eq!(start_interpreter(&p), $expected);
Ok(())
},
Err(e) => Err(format!("{:?}",e)),
}
}
)}

graceful coral
#

And what is program? Also: please use code blocks for code

#

-code

deep wingBOT
#

Please post your code examples and compiler output with code fences (```) around them. Example:
```rust
let (x, y) = (0, 42);
println!("Position at {}, {}", x, y);
```

let (x, y) = (0, 42);
println!("Position at {}, {}", x, y);

If the snippet is long or you want to demonstrate something, consider sharing it through the playground: https://play.rust-lang.org/ or https://www.rustexplorer.com/ or https://paste.rs/web.
Please avoid sharing screenshots of your code, as they're not very accessible. Using code fences or a shared snippet makes the code more readable and allows those helping you to copy-paste the code to help explain things.

remote yoke
graceful coral
#

Your comparison parser only parses a value, an operator, and a value, but the example you gave it is value, op, value, op, value (i.e. chained comparisons).

remote yoke
graceful coral
#

You'll probably need to take operator precedence into account in your parser

#

reference.txt (I'm assuming the assignment description> says

A conditional expressions is a number, boolean, identifier or expression; followed by one of the noted operators below; followed by another number, boolean, identifier or expression. Here are some examples of valid and invalid conditional expressions.
but your grammar.ebnf (I'm assuming you wrote this) file only says that a comparison has value on either side, so they aren't describing the same grammar

remote yoke
#

but i still don't get it tho

#

and please don't mind me i'm still very beginner with all this

#

and very new to rust

#

and my idea was to change that comparison function like this

#

pub fn comparison(input: &str) -> IResult<&str, Node> {

#

like to change the function comparision

#

so that it will parse multiple comparison at once that's when i struggle the most

#

i don't know how to make that switch

graceful coral
#

You may need to split it into multiple functions, one for each precedence level.
Or you could keep parsing value, op, value, op, ... and do the precedence handling manually afterwards

remote yoke
#

can you help me do that cuz i'm really lost on where i start like let's say now we have this function ```rust

pub fn comparison(input: &str) -> IResult<&str, Node> {
let (input, left) = value(input)?;
let (input, _) = many0(tag(" "))(input)?;
let (input, operator) = alt((
tag("=="), tag("!="), tag("<="), tag(">="), tag("<"), tag(">")
))(input)?;
let (input, _) = many0(tag(" "))(input)?;
let (input, right) = value(input)?;
let children = vec![left, right];
let name = match operator {
"==" => "==",
"!=" => "!=",
"<=" => "<=",
">=" => ">=",
"<" => "<",
">" => ">",
_ => return Err(nom::Err::Failure(nom::error::Error::new(input, nom::error::ErrorKind::Tag)))
};
Ok((input, Node::ComparisonExpression { name: name.to_string(), children }))
}```

#

how can i change it to give me what we want