fix binop rhs precedence

This commit is contained in:
nora 2021-10-31 20:44:11 +01:00
parent 7b1c7335c2
commit 87790d4049
4 changed files with 20 additions and 25 deletions

View file

@ -52,19 +52,19 @@
<expression> ::= <logical-or> <expression> ::= <logical-or>
<logical-or> ::= <logical-and> { "or" <logical-and> } <logical-or> ::= <logical-and> { "or" <logical-or> }
<logical-and> ::= <equality> { "and" <equality> } <logical-and> ::= <equality> { "and" <logical-and> }
<equality> ::= <comparison> { ("!=" | "==") <comparison> } <equality> ::= <comparison> { ("!=" | "==") <comparison> }
<comparison> ::= <term> { (">" | "<" | ">=" | "<=") <term> } <comparison> ::= <term> { (">" | "<" | ">=" | "<=") <term> }
<term> ::= <factor> { ("-" | "+") <factor> } <term> ::= <factor> { ("-" | "+") <term> }
<factor> ::= <unary> { ( "*" | "/" | "%" ) <unary> } <factor> ::= <unary> { ( "*" | "/" | "%" ) <factor> }
<unary> ::= { ( "not" | "-" ) } <primary> <unary> ::= { ( "not" | "-" ) } <unary>
<primary> ::= <IDENT> <primary> ::= <IDENT>
| <NUMBER> | <NUMBER>

View file

@ -20,9 +20,7 @@ pub fn run_program(program: &str) {
match ast { match ast {
Ok(ast) => println!("{:#?}", ast), Ok(ast) => println!("{:#?}", ast),
Err(err) => { Err(err) => errors::display_error(program, err),
eprintln!("{:?}", err)
}
} }
} else { } else {
errors errors

View file

@ -225,7 +225,7 @@ impl<'code> Parser<'code> {
fn logical_or(&mut self) -> ParseResult<'code, Expr> { fn logical_or(&mut self) -> ParseResult<'code, Expr> {
let lhs = self.logical_and()?; let lhs = self.logical_and()?;
match self.peek_kind() { match self.peek_kind() {
Some(TokenType::Or) => parse_bin_op!(self, lhs, BinaryOpKind::Or, logical_and), Some(TokenType::Or) => parse_bin_op!(self, lhs, BinaryOpKind::Or, logical_or),
_ => Ok(lhs), _ => Ok(lhs),
} }
} }
@ -233,7 +233,7 @@ impl<'code> Parser<'code> {
fn logical_and(&mut self) -> ParseResult<'code, Expr> { fn logical_and(&mut self) -> ParseResult<'code, Expr> {
let lhs = self.equality()?; let lhs = self.equality()?;
match self.peek_kind() { match self.peek_kind() {
Some(TokenType::And) => parse_bin_op!(self, lhs, BinaryOpKind::And, equality), Some(TokenType::And) => parse_bin_op!(self, lhs, BinaryOpKind::And, logical_and),
_ => Ok(lhs), _ => Ok(lhs),
} }
} }
@ -269,8 +269,8 @@ impl<'code> Parser<'code> {
fn term(&mut self) -> ParseResult<'code, Expr> { fn term(&mut self) -> ParseResult<'code, Expr> {
let lhs = self.factor()?; let lhs = self.factor()?;
match self.peek_kind() { match self.peek_kind() {
Some(TokenType::Plus) => parse_bin_op!(self, lhs, BinaryOpKind::Add, factor), Some(TokenType::Plus) => parse_bin_op!(self, lhs, BinaryOpKind::Add, term),
Some(TokenType::Minus) => parse_bin_op!(self, lhs, BinaryOpKind::Sub, factor), Some(TokenType::Minus) => parse_bin_op!(self, lhs, BinaryOpKind::Sub, term),
_ => Ok(lhs), _ => Ok(lhs),
} }
} }
@ -278,9 +278,9 @@ impl<'code> Parser<'code> {
fn factor(&mut self) -> ParseResult<'code, Expr> { fn factor(&mut self) -> ParseResult<'code, Expr> {
let lhs = self.unary()?; let lhs = self.unary()?;
match self.peek_kind() { match self.peek_kind() {
Some(TokenType::Asterisk) => parse_bin_op!(self, lhs, BinaryOpKind::Mul, unary), Some(TokenType::Asterisk) => parse_bin_op!(self, lhs, BinaryOpKind::Mul, factor),
Some(TokenType::Slash) => parse_bin_op!(self, lhs, BinaryOpKind::Div, unary), Some(TokenType::Slash) => parse_bin_op!(self, lhs, BinaryOpKind::Div, factor),
Some(TokenType::Percent) => parse_bin_op!(self, lhs, BinaryOpKind::Mod, unary), Some(TokenType::Percent) => parse_bin_op!(self, lhs, BinaryOpKind::Mod, factor),
_ => Ok(lhs), _ => Ok(lhs),
} }
} }
@ -289,7 +289,7 @@ impl<'code> Parser<'code> {
match self.peek_kind() { match self.peek_kind() {
Some(TokenType::Not) => { Some(TokenType::Not) => {
let unary_op_span = self.next().unwrap().span; let unary_op_span = self.next().unwrap().span;
let expr = self.expression()?; let expr = self.unary()?;
Ok(Expr::UnaryOp(Box::new(UnaryOp { Ok(Expr::UnaryOp(Box::new(UnaryOp {
span: unary_op_span.extend(expr.span()), span: unary_op_span.extend(expr.span()),
expr, expr,
@ -298,7 +298,7 @@ impl<'code> Parser<'code> {
} }
Some(TokenType::Minus) => { Some(TokenType::Minus) => {
let unary_op_span = self.next().unwrap().span; let unary_op_span = self.next().unwrap().span;
let expr = self.expression()?; let expr = self.unary()?;
Ok(Expr::UnaryOp(Box::new(UnaryOp { Ok(Expr::UnaryOp(Box::new(UnaryOp {
span: unary_op_span.extend(expr.span()), span: unary_op_span.extend(expr.span()),
expr, expr,
@ -450,16 +450,16 @@ impl CompilerError for ParseErr<'_> {
fn message(&self) -> String { fn message(&self) -> String {
match self { match self {
ParseErr::MismatchedKind { expected, actual } => { ParseErr::MismatchedKind { expected, actual } => {
format!("expected: {:?}, received: {:?}", expected, actual.kind) format!("expected `{:?}`, received `{:?}`", expected, actual.kind)
} }
ParseErr::InvalidTokenPrimary(token) => { ParseErr::InvalidTokenPrimary(token) => {
format!("invalid token in expression: {:?}", token.kind) format!("invalid token in expression: `{:?}`", token.kind)
} }
ParseErr::EOFExpecting(token) => { ParseErr::EOFExpecting(token) => {
format!("reached EOF searching for: {:?}", token) format!("reached EOF searching for `{:?}`", token)
} }
ParseErr::EOF(message) => { ParseErr::EOF(message) => {
format!("reached EOF while parsing: {}", message) format!("reached EOF while parsing `{}`", message)
} }
ParseErr::BreakOutsideLoop(_) => "break used outside of loop".to_string(), ParseErr::BreakOutsideLoop(_) => "break used outside of loop".to_string(),
ParseErr::ReturnOutsideFunction(_) => "return used outside of function".to_string(), ParseErr::ReturnOutsideFunction(_) => "return used outside of function".to_string(),

View file

@ -1,6 +1,3 @@
fn test() { fn test() {
let uwu = 2; "u" + "w" + "u";
if uwu {
print;
}
} }