mirror of
https://github.com/rm-dr/daisy
synced 2025-07-14 00:14:48 -07:00
Added square root, fixed many parser bugs
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use crate::parser::PreToken;
|
||||
use crate::tokens::LineLocation;
|
||||
use crate::parser::LineLocation;
|
||||
|
||||
|
||||
pub(in crate::parser) fn find_subs(
|
||||
@ -64,7 +64,10 @@ pub(in crate::parser) fn find_subs(
|
||||
"chi" => {Some("χ")},
|
||||
"psi" => {Some("ψ")},
|
||||
"omega" => {Some("ω")},
|
||||
|
||||
// Operators
|
||||
"sqrt" => {Some("√")},
|
||||
"rt" => {Some("√")},
|
||||
|
||||
_ => {None}
|
||||
};
|
||||
|
@ -1,16 +1,28 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use crate::tokens::LineLocation;
|
||||
use crate::tokens::Operator;
|
||||
use crate::parser::PreToken;
|
||||
|
||||
use crate::parser::LineLocation;
|
||||
use crate::parser::ParserError;
|
||||
|
||||
use crate::tokens::Operator;
|
||||
|
||||
// Inserts implicit operators
|
||||
fn lookback(
|
||||
g: &mut VecDeque<PreToken>
|
||||
) -> Result<(), (LineLocation, ParserError)> {
|
||||
if g.len() >= 2 {
|
||||
if g.len() == 1 {
|
||||
let a: PreToken = g.pop_back().unwrap();
|
||||
match &a {
|
||||
PreToken::PreOperator(l,o)
|
||||
=> {
|
||||
if o == "-" {
|
||||
g.push_back(PreToken::PreOperator(*l, String::from("neg")));
|
||||
} else { g.push_back(a); }
|
||||
},
|
||||
_ => { g.push_back(a); }
|
||||
};
|
||||
|
||||
} else {
|
||||
let b: PreToken = g.pop_back().unwrap();
|
||||
let a: PreToken = g.pop_back().unwrap();
|
||||
|
||||
@ -42,10 +54,58 @@ fn lookback(
|
||||
));
|
||||
}
|
||||
|
||||
// The following are fine
|
||||
(PreToken::PreOperator(_,_), _) |
|
||||
(_, PreToken::PreOperator(_,_))
|
||||
=> { g.push_back(a); g.push_back(b); },
|
||||
(PreToken::PreOperator(_, sa), PreToken::PreOperator(l,sb))
|
||||
=> {
|
||||
if sb == "-" && {
|
||||
let o = Operator::from_string(sa);
|
||||
|
||||
o.is_some() &&
|
||||
(
|
||||
o.unwrap().is_binary() ||
|
||||
!o.unwrap().is_left_associative()
|
||||
)
|
||||
} {
|
||||
g.push_back(a);
|
||||
g.push_back(PreToken::PreOperator(*l, String::from("neg")));
|
||||
} else { g.push_back(a); g.push_back(b); }
|
||||
}
|
||||
|
||||
// Insert implicit multiplications for unary operators
|
||||
(PreToken::PreNumber(_,_), PreToken::PreOperator(l,s))
|
||||
| (PreToken::PreGroup(_,_), PreToken::PreOperator(l,s))
|
||||
| (PreToken::PreWord(_,_), PreToken::PreOperator(l,s))
|
||||
=> {
|
||||
let o = Operator::from_string(s);
|
||||
g.push_back(a);
|
||||
if o.is_some() {
|
||||
let o = o.unwrap();
|
||||
if (!o.is_binary()) && (!o.is_left_associative()) {
|
||||
g.push_back(PreToken::PreOperator(
|
||||
LineLocation{pos: l.pos-1, len: 0},
|
||||
String::from("i*")
|
||||
));
|
||||
}
|
||||
}
|
||||
g.push_back(b);
|
||||
},
|
||||
|
||||
(PreToken::PreOperator(_,s), PreToken::PreNumber(l,_))
|
||||
| (PreToken::PreOperator(_,s), PreToken::PreGroup(l,_))
|
||||
| (PreToken::PreOperator(_,s), PreToken::PreWord(l,_))
|
||||
=> {
|
||||
let o = Operator::from_string(s);
|
||||
g.push_back(a);
|
||||
if o.is_some() {
|
||||
let o = o.unwrap();
|
||||
if (!o.is_binary()) && o.is_left_associative() {
|
||||
g.push_back(PreToken::PreOperator(
|
||||
LineLocation{pos: l.pos-1, len: 0},
|
||||
String::from("i*")
|
||||
));
|
||||
}
|
||||
}
|
||||
g.push_back(b);
|
||||
},
|
||||
|
||||
// This shouldn't ever happen.
|
||||
(PreToken::PreGroupStart(_), _)
|
||||
@ -102,16 +162,6 @@ pub(in crate::parser) fn groupify(
|
||||
lookback(v_now)?;
|
||||
},
|
||||
|
||||
PreToken::PreWord(ref l, ref s) => {
|
||||
let o = Operator::from_string(&s[..]);
|
||||
if o.is_some() {
|
||||
v_now.push_back(PreToken::PreOperator(*l, s.clone()));
|
||||
} else {
|
||||
v_now.push_back(t);
|
||||
}
|
||||
lookback(v_now)?;
|
||||
}
|
||||
|
||||
_ => {
|
||||
v_now.push_back(t);
|
||||
lookback(v_now)?;
|
||||
|
@ -12,9 +12,17 @@ use crate::parser::groupify::groupify;
|
||||
use crate::parser::treeify::treeify;
|
||||
use crate::parser::find_subs::find_subs;
|
||||
|
||||
use crate::tokens::LineLocation;
|
||||
use crate::tokens::Token;
|
||||
|
||||
/// Specifies the location of a token in an input string.
|
||||
/// Used to locate ParserErrors.
|
||||
#[derive(Debug)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LineLocation {
|
||||
pub pos: usize,
|
||||
pub len: usize
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum PreToken {
|
||||
PreNumber(LineLocation, String),
|
||||
@ -67,14 +75,14 @@ impl PreToken {
|
||||
Ok(n) => n,
|
||||
Err(_) => return Err((l, ParserError::BadNumber))
|
||||
};
|
||||
return Ok(Token::Number(l, n));
|
||||
return Ok(Token::Number(n));
|
||||
},
|
||||
PreToken::PreWord(l, s) => {
|
||||
return Ok(match &s[..] {
|
||||
// Mathematical constants
|
||||
"π"|"pi" => { Token::Constant(l, 3.141592653, String::from("pi")) },
|
||||
"e" => { Token::Constant(l, 2.71828, String::from("e")) },
|
||||
"phi"|"φ" => { Token::Constant(l, 1.61803, String::from("phi")) },
|
||||
"π"|"pi" => { Token::Constant(3.141592653, String::from("pi")) },
|
||||
"e" => { Token::Constant(2.71828, String::from("e")) },
|
||||
"phi"|"φ" => { Token::Constant(1.61803, String::from("phi")) },
|
||||
_ => { return Err((l, ParserError::Undefined(s))); }
|
||||
});
|
||||
}
|
||||
|
@ -1,28 +1,44 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use crate::parser::PreToken;
|
||||
use crate::tokens::LineLocation;
|
||||
use crate::parser::LineLocation;
|
||||
|
||||
/// Updates the length of a Token's LineLocation.
|
||||
/// Run whenever a token is finished.
|
||||
use crate::tokens::Operator;
|
||||
|
||||
// Called whenever a token is finished.
|
||||
#[inline(always)]
|
||||
fn update_line_location(mut t: PreToken, stop_i: usize) -> PreToken {
|
||||
fn push_token(g: &mut VecDeque<PreToken>, t: Option<PreToken>, stop_i: usize) {
|
||||
|
||||
if t.is_none() { return }
|
||||
let mut t = t.unwrap();
|
||||
|
||||
match t {
|
||||
PreToken::PreGroupStart(ref mut l) |
|
||||
PreToken::PreGroupEnd(ref mut l) |
|
||||
PreToken::PreOperator(ref mut l, _) |
|
||||
PreToken::PreNumber(ref mut l, _) |
|
||||
PreToken::PreWord(ref mut l, _)
|
||||
PreToken::PreGroupStart(ref mut l)
|
||||
| PreToken::PreGroupEnd(ref mut l)
|
||||
| PreToken::PreOperator(ref mut l, _)
|
||||
| PreToken::PreNumber(ref mut l, _)
|
||||
| PreToken::PreWord(ref mut l, _)
|
||||
=> {
|
||||
*l = LineLocation{
|
||||
pos: l.pos,
|
||||
len: stop_i - l.pos,
|
||||
};
|
||||
},
|
||||
_ => panic!()
|
||||
|
||||
PreToken::PreGroup(_,_)
|
||||
| PreToken::Container(_)
|
||||
=> panic!()
|
||||
};
|
||||
|
||||
return t;
|
||||
|
||||
if let PreToken::PreWord(l, s) = &t {
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_some() {
|
||||
t = PreToken::PreOperator(*l, s.clone());
|
||||
}
|
||||
}
|
||||
|
||||
g.push_back(t);
|
||||
}
|
||||
|
||||
/// Turns a string into Tokens. First stage of parsing.
|
||||
@ -36,27 +52,11 @@ pub(in crate::parser) fn tokenize(input: &String) -> VecDeque<PreToken> {
|
||||
// The minus sign can be both a Negative and an Operator.
|
||||
// Needs special treatment.
|
||||
'-' => {
|
||||
if t.is_some() { g.push_back(update_line_location(t.unwrap(), i)); }
|
||||
match g.back().as_ref() {
|
||||
// If previous token was any of the following,
|
||||
// this is the "minus" operator
|
||||
Some(PreToken::PreNumber(_, _)) |
|
||||
Some(PreToken::PreGroupEnd(_)) |
|
||||
Some(PreToken::PreWord(_, _)) => {
|
||||
t = Some(PreToken::PreOperator(
|
||||
LineLocation{pos: i, len: 1},
|
||||
String::from("-")
|
||||
));
|
||||
},
|
||||
|
||||
// Otherwise, this is a negative sign.
|
||||
_ => {
|
||||
t = Some(PreToken::PreOperator(
|
||||
LineLocation{pos: i, len: 1},
|
||||
String::from("neg")
|
||||
));
|
||||
}
|
||||
};
|
||||
push_token(&mut g, t, i);
|
||||
t = Some(PreToken::PreOperator(
|
||||
LineLocation{pos: i, len: 1},
|
||||
String::from("-")
|
||||
));
|
||||
},
|
||||
|
||||
// Number
|
||||
@ -72,7 +72,7 @@ pub(in crate::parser) fn tokenize(input: &String) -> VecDeque<PreToken> {
|
||||
// If we're not building a number, finalize
|
||||
// previous token and start one.
|
||||
_ => {
|
||||
if t.is_some() { g.push_back(update_line_location(t.unwrap(), i)); }
|
||||
push_token(&mut g, t, i);
|
||||
t = Some(PreToken::PreNumber(LineLocation{pos: i, len: 0}, String::from(c)));
|
||||
}
|
||||
};
|
||||
@ -85,7 +85,7 @@ pub(in crate::parser) fn tokenize(input: &String) -> VecDeque<PreToken> {
|
||||
match &mut t {
|
||||
Some(PreToken::PreOperator(_, val)) => { val.push(c); },
|
||||
_ => {
|
||||
if t.is_some() { g.push_back(update_line_location(t.unwrap(), i)); }
|
||||
push_token(&mut g, t, i);
|
||||
t = Some(PreToken::PreOperator(LineLocation{pos: i, len: 0}, String::from(c)));
|
||||
}
|
||||
};
|
||||
@ -93,20 +93,18 @@ pub(in crate::parser) fn tokenize(input: &String) -> VecDeque<PreToken> {
|
||||
|
||||
// Group
|
||||
'(' => {
|
||||
if t.is_some() { g.push_back(update_line_location(t.unwrap(), i)); }
|
||||
push_token(&mut g, t, i);
|
||||
t = Some(PreToken::PreGroupStart(LineLocation{pos: i, len: 0}));
|
||||
},
|
||||
')' => {
|
||||
if t.is_some() { g.push_back(update_line_location(t.unwrap(), i)); }
|
||||
push_token(&mut g, t, i);
|
||||
t = Some(PreToken::PreGroupEnd(LineLocation{pos: i, len: 0}));
|
||||
},
|
||||
|
||||
// Space. Basic seperator.
|
||||
' ' => {
|
||||
if t.is_some() {
|
||||
g.push_back(update_line_location(t.unwrap(), i));
|
||||
t = None;
|
||||
}
|
||||
push_token(&mut g, t, i);
|
||||
t = None;
|
||||
}
|
||||
|
||||
// Word
|
||||
@ -115,7 +113,7 @@ pub(in crate::parser) fn tokenize(input: &String) -> VecDeque<PreToken> {
|
||||
Some(PreToken::PreWord(_, val)) => { val.push(c); },
|
||||
|
||||
_ => {
|
||||
if t.is_some() { g.push_back(update_line_location(t.unwrap(), i)); }
|
||||
push_token(&mut g, t, i);
|
||||
t = Some(PreToken::PreWord(LineLocation{pos: i, len: 0}, String::from(c)));
|
||||
}
|
||||
};
|
||||
@ -123,7 +121,7 @@ pub(in crate::parser) fn tokenize(input: &String) -> VecDeque<PreToken> {
|
||||
};
|
||||
}
|
||||
|
||||
if t.is_some() { g.push_back(update_line_location(t.unwrap(), input.chars().count())); }
|
||||
push_token(&mut g, t, input.chars().count());
|
||||
|
||||
return g;
|
||||
}
|
@ -3,17 +3,14 @@ use std::collections::VecDeque;
|
||||
|
||||
use crate::parser::PreToken;
|
||||
use crate::parser::ParserError;
|
||||
use crate::parser::LineLocation;
|
||||
|
||||
use crate::tokens::Token;
|
||||
use crate::tokens::Operator;
|
||||
use crate::tokens::LineLocation;
|
||||
|
||||
|
||||
|
||||
fn treeify_binary(
|
||||
i: usize,
|
||||
g_inner: &mut VecDeque<PreToken>,
|
||||
left_associative: bool
|
||||
g_inner: &mut VecDeque<PreToken>
|
||||
) -> Result<(), (LineLocation, ParserError)> {
|
||||
|
||||
let this: &PreToken = &g_inner[i];
|
||||
@ -27,45 +24,44 @@ fn treeify_binary(
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
|
||||
let next: &PreToken;
|
||||
if left_associative {
|
||||
next = {
|
||||
if i < g_inner.len()-1 {
|
||||
&g_inner[i+1]
|
||||
} else {
|
||||
let l = match this {
|
||||
PreToken::PreOperator(l, _) => l,
|
||||
_ => panic!()
|
||||
};
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
};
|
||||
} else {
|
||||
next = {
|
||||
if i > 0 {
|
||||
&g_inner[i-1]
|
||||
} else {
|
||||
let l = match this {
|
||||
PreToken::PreOperator(l, _) => l,
|
||||
_ => panic!()
|
||||
};
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let left = {
|
||||
if i > 0 {
|
||||
&g_inner[i-1]
|
||||
} else {
|
||||
let l = match this {
|
||||
PreToken::PreOperator(l, _) => l,
|
||||
_ => panic!()
|
||||
};
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
};
|
||||
|
||||
let right = {
|
||||
if i < g_inner.len()-1 {
|
||||
&g_inner[i+1]
|
||||
} else {
|
||||
let l = match this {
|
||||
PreToken::PreOperator(l, _) => l,
|
||||
_ => panic!()
|
||||
};
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
if let PreToken::PreOperator(l, s) = next {
|
||||
|
||||
|
||||
if let PreToken::PreOperator(l, s) = left {
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
let o = o.unwrap();
|
||||
|
||||
if {
|
||||
(!o.is_binary()) &&
|
||||
!(o.is_left_associative() && left_associative)
|
||||
o.is_left_associative()
|
||||
} {
|
||||
// Only right-associative unary operators can follow a binary operator
|
||||
return Ok(());
|
||||
} else {
|
||||
let tl = *this.get_line_location();
|
||||
@ -74,59 +70,79 @@ fn treeify_binary(
|
||||
ParserError::Syntax
|
||||
));
|
||||
}
|
||||
} else {
|
||||
// Precedence of this operator
|
||||
let this_val = {
|
||||
let PreToken::PreOperator(l, s) = this else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
o.unwrap() as isize
|
||||
};
|
||||
}
|
||||
|
||||
// Precedence of the operators contesting our arguments
|
||||
let left_val = if i > 1 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i-2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap() as isize)
|
||||
} else { None };
|
||||
|
||||
let right_val = if i < g_inner.len()-2 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i+2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap() as isize)
|
||||
} else { None };
|
||||
if let PreToken::PreOperator(l, s) = right {
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
let o = o.unwrap();
|
||||
|
||||
if {
|
||||
(left_val.is_none() || this_val >= left_val.unwrap()) &&
|
||||
(right_val.is_none() || this_val >= right_val.unwrap())
|
||||
(!o.is_binary()) &&
|
||||
!o.is_left_associative()
|
||||
} {
|
||||
// This operator has higher precedence, it takes both arguments
|
||||
let left_pre = g_inner.remove(i-1).unwrap();
|
||||
let this_pre = g_inner.remove(i-1).unwrap();
|
||||
let right_pre = g_inner.remove(i-1).unwrap();
|
||||
let left: Token; let right: Token;
|
||||
if let PreToken::PreGroup(_, _) = right_pre { right = treeify(right_pre)?; } else {right = right_pre.to_token()?;}
|
||||
if let PreToken::PreGroup(_, _) = left_pre { left = treeify(left_pre)?; } else {left = left_pre.to_token()?;}
|
||||
|
||||
let (l, o) = {
|
||||
let PreToken::PreOperator(l, s) = this_pre else {panic!()};
|
||||
let o = Operator::from_string(&s);
|
||||
if o.is_none() { panic!() }
|
||||
(l, o.unwrap())
|
||||
};
|
||||
|
||||
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(2);
|
||||
new_token_args.push_back(left);
|
||||
new_token_args.push_back(right);
|
||||
|
||||
g_inner.insert(i-1, PreToken::Container(o.into_token(l, new_token_args)));
|
||||
|
||||
return Ok(());
|
||||
} else {
|
||||
return Ok(());
|
||||
let tl = *this.get_line_location();
|
||||
return Err((
|
||||
LineLocation{pos: tl.pos, len: l.pos - tl.pos + l.len},
|
||||
ParserError::Syntax
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Precedence of this operator
|
||||
let this_val = {
|
||||
let PreToken::PreOperator(l, s) = this else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
o.unwrap() as isize
|
||||
};
|
||||
|
||||
// Precedence of the operators contesting our arguments
|
||||
let left_val = if i > 1 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i-2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap() as isize)
|
||||
} else { None };
|
||||
|
||||
let right_val = if i < g_inner.len()-2 {
|
||||
let PreToken::PreOperator(l, s) = &g_inner[i+2] else {panic!()};
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
Some(o.unwrap() as isize)
|
||||
} else { None };
|
||||
|
||||
if {
|
||||
(left_val.is_none() || this_val >= left_val.unwrap()) &&
|
||||
(right_val.is_none() || this_val >= right_val.unwrap())
|
||||
} {
|
||||
// This operator has higher precedence, it takes both arguments
|
||||
let left_pre = g_inner.remove(i-1).unwrap();
|
||||
let this_pre = g_inner.remove(i-1).unwrap();
|
||||
let right_pre = g_inner.remove(i-1).unwrap();
|
||||
let left: Token; let right: Token;
|
||||
if let PreToken::PreGroup(_, _) = right_pre { right = treeify(right_pre)?; } else {right = right_pre.to_token()?;}
|
||||
if let PreToken::PreGroup(_, _) = left_pre { left = treeify(left_pre)?; } else {left = left_pre.to_token()?;}
|
||||
|
||||
let o = {
|
||||
let PreToken::PreOperator(_, s) = this_pre else {panic!()};
|
||||
let o = Operator::from_string(&s);
|
||||
if o.is_none() { panic!() }
|
||||
o.unwrap()
|
||||
};
|
||||
|
||||
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(2);
|
||||
new_token_args.push_back(left);
|
||||
new_token_args.push_back(right);
|
||||
|
||||
g_inner.insert(i-1, PreToken::Container(o.into_token(new_token_args)));
|
||||
|
||||
return Ok(());
|
||||
} else {
|
||||
return Ok(());
|
||||
};
|
||||
}
|
||||
|
||||
@ -174,14 +190,7 @@ fn treeify_unary(
|
||||
}
|
||||
|
||||
if prev.is_some() {
|
||||
if let PreToken::PreOperator(l, s) = prev.unwrap() {
|
||||
let o = Operator::from_string(s);
|
||||
if o.is_none() { return Err((*l, ParserError::Syntax)); }
|
||||
let o = o.unwrap();
|
||||
|
||||
if o.is_left_associative() && left_associative {
|
||||
return Err((*l, ParserError::Syntax));
|
||||
}
|
||||
if let PreToken::PreOperator(_,_) = prev.unwrap() {
|
||||
} else {
|
||||
return Err((
|
||||
*this.get_line_location(),
|
||||
@ -190,8 +199,6 @@ fn treeify_unary(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if let PreToken::PreOperator(l, _) = next {
|
||||
let tl = *this.get_line_location();
|
||||
return Err((
|
||||
@ -236,20 +243,20 @@ fn treeify_unary(
|
||||
}
|
||||
if let PreToken::PreGroup(_, _) = next_pre { next = treeify(next_pre)?; } else { next = next_pre.to_token()? }
|
||||
|
||||
let (l, o) = {
|
||||
let PreToken::PreOperator(l, s) = this_pre else {panic!()};
|
||||
let o = {
|
||||
let PreToken::PreOperator(_, s) = this_pre else {panic!()};
|
||||
let o = Operator::from_string(&s);
|
||||
if o.is_none() { panic!() }
|
||||
(l, o.unwrap())
|
||||
o.unwrap()
|
||||
};
|
||||
|
||||
let mut new_token_args: VecDeque<Token> = VecDeque::with_capacity(3);
|
||||
new_token_args.push_back(next);
|
||||
|
||||
if left_associative {
|
||||
g_inner.insert(i-1, PreToken::Container(o.into_token(l, new_token_args)));
|
||||
g_inner.insert(i-1, PreToken::Container(o.into_token(new_token_args)));
|
||||
} else {
|
||||
g_inner.insert(i, PreToken::Container(o.into_token(l, new_token_args)));
|
||||
g_inner.insert(i, PreToken::Container(o.into_token(new_token_args)));
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
@ -300,7 +307,7 @@ pub(in crate::parser) fn treeify(
|
||||
if left_associative {
|
||||
if this_op.is_left_associative() {
|
||||
if this_op.is_binary() {
|
||||
treeify_binary(i, g_inner, left_associative)?;
|
||||
treeify_binary(i, g_inner)?;
|
||||
} else {
|
||||
treeify_unary(i, g_inner, left_associative)?;
|
||||
}
|
||||
@ -309,7 +316,7 @@ pub(in crate::parser) fn treeify(
|
||||
} else {
|
||||
if !this_op.is_left_associative() {
|
||||
if this_op.is_binary() {
|
||||
treeify_binary(i, g_inner, left_associative)?;
|
||||
treeify_binary(i, g_inner)?;
|
||||
} else {
|
||||
treeify_unary(i, g_inner, left_associative)?;
|
||||
}
|
||||
|
Reference in New Issue
Block a user