mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
fix binop rhs precedence
This commit is contained in:
parent
7b1c7335c2
commit
87790d4049
4 changed files with 20 additions and 25 deletions
10
grammar.txt
10
grammar.txt
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
5
test.sl
5
test.sl
|
|
@ -1,6 +1,3 @@
|
||||||
fn test() {
|
fn test() {
|
||||||
let uwu = 2;
|
"u" + "w" + "u";
|
||||||
if uwu {
|
|
||||||
print;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue