lex: add a couple more operators

main
anna 2 years ago
parent 7b7cd933d3
commit 10ca36535f
Signed by: fef
GPG Key ID: EC22E476DC2D3D84

@ -0,0 +1,17 @@
L2R: ,
R2L: = += -= *= **= /= %= &= |= ^= <<= >>=
L2R: ||
L2R: &&
L2R: == != < <= > >=
L2R: |
L2R: ^
L2R: &
L2R: << >>
L2R: + - (binary minus)
L2R: * / %
L2R: **
R2L: ! - (unary minus)
L2R: () [] .
line numbers are precedence values
higher values mean higher precedence

@ -41,11 +41,87 @@ pub enum Node {
#[derive(Debug)]
pub enum Operator {
Eq,
EqEq,
Bang,
BangEq,
Gt,
GtGt,
GtEq,
GtGtEq,
Lt,
LtLt,
LtEq,
LtLtEq,
Plus,
PlusEq,
Minus,
MinusEq,
Asterisk,
AsteriskAsterisk,
AsteriskEq,
AsteriskAsteriskEq,
Slash,
SlashEq,
Percent,
PercentEq,
Pipe,
PipePipe,
PipeEq,
Amp,
AmpAmp,
AmpEq,
Caret,
CaretEq,
}
impl Operator {
pub const fn precedence(&self) -> u8 {
match self {
Operator::Eq => 2,
Operator::PlusEq => 2,
Operator::MinusEq => 2,
Operator::AsteriskEq => 2,
Operator::AsteriskAsteriskEq => 2,
Operator::SlashEq => 2,
Operator::PercentEq => 2,
Operator::AmpEq => 2,
Operator::PipeEq => 2,
Operator::CaretEq => 2,
Operator::GtGtEq => 2,
Operator::LtLtEq => 2,
Operator::PipePipe => 3,
Operator::AmpAmp => 4,
Operator::EqEq => 5,
Operator::BangEq => 5,
Operator::Lt => 5,
Operator::LtEq => 5,
Operator::Gt => 5,
Operator::GtEq => 5,
Operator::Pipe => 6,
Operator::Caret => 7,
Operator::Amp => 8,
Operator::GtGt => 9,
Operator::LtLt => 9,
Operator::Plus => 10,
Operator::Minus => 10,
Operator::Asterisk => 11,
Operator::Slash => 11,
Operator::Percent => 11,
Operator::AsteriskAsterisk => 12,
Operator::Bang => 13,
}
}
}
impl Node {
@ -92,7 +168,7 @@ impl Node {
impl fmt::Display for Node {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mut tmp: String;
let tmp: String;
write!(
f,
"{}",
@ -121,11 +197,37 @@ impl Operator {
pub fn from_token(token: &Token) -> Result<Operator, Error> {
match token.kind {
token::Kind::Eq => Ok(Operator::Eq),
token::Kind::EqEq => Ok(Operator::EqEq),
token::Kind::BangEq => Ok(Operator::BangEq),
token::Kind::Bang => Ok(Operator::Bang),
token::Kind::Gt => Ok(Operator::Gt),
token::Kind::GtGt => Ok(Operator::GtGt),
token::Kind::GtEq => Ok(Operator::GtEq),
token::Kind::GtGtEq => Ok(Operator::GtGtEq),
token::Kind::Lt => Ok(Operator::Lt),
token::Kind::LtLt => Ok(Operator::LtLt),
token::Kind::LtEq => Ok(Operator::LtEq),
token::Kind::LtLtEq => Ok(Operator::LtLtEq),
token::Kind::Plus => Ok(Operator::Plus),
token::Kind::PlusEq => Ok(Operator::PlusEq),
token::Kind::Minus => Ok(Operator::Minus),
token::Kind::MinusEq => Ok(Operator::MinusEq),
token::Kind::Asterisk => Ok(Operator::Asterisk),
token::Kind::AsteriskAsterisk => Ok(Operator::AsteriskAsterisk),
token::Kind::AsteriskEq => Ok(Operator::AsteriskEq),
token::Kind::AsteriskAsteriskEq => Ok(Operator::AsteriskAsteriskEq),
token::Kind::Slash => Ok(Operator::Slash),
token::Kind::SlashEq => Ok(Operator::SlashEq),
token::Kind::Percent => Ok(Operator::Percent),
token::Kind::PercentEq => Ok(Operator::PercentEq),
token::Kind::Pipe => Ok(Operator::Pipe),
token::Kind::PipePipe => Ok(Operator::PipePipe),
token::Kind::PipeEq => Ok(Operator::PipeEq),
token::Kind::Amp => Ok(Operator::Amp),
token::Kind::AmpAmp => Ok(Operator::AmpAmp),
token::Kind::AmpEq => Ok(Operator::AmpEq),
token::Kind::Caret => Ok(Operator::Caret),
token::Kind::CaretEq => Ok(Operator::CaretEq),
_ => Err(Error::syntax_error(
token.pos.clone(),
format!("\"{}\" is not an operator", token.raw),
@ -136,11 +238,37 @@ impl Operator {
pub fn raw(&self) -> &'static str {
match self {
Operator::Eq => "=",
Operator::EqEq => "==",
Operator::BangEq => "!=",
Operator::Gt => ">",
Operator::GtGt => ">>",
Operator::GtEq => ">=",
Operator::GtGtEq => ">>=",
Operator::Lt => "<",
Operator::LtLt => "<<",
Operator::LtEq => "<=",
Operator::LtLtEq => "<<=",
Operator::Plus => "+",
Operator::PlusEq => "+=",
Operator::Minus => "-",
Operator::MinusEq => "-=",
Operator::Asterisk => "*",
Operator::AsteriskAsterisk => "**",
Operator::AsteriskEq => "*=",
Operator::AsteriskAsteriskEq => "**=",
Operator::Slash => "/",
Operator::SlashEq => "/=",
Operator::Percent => "%",
Operator::PercentEq => "%=",
Operator::Bang => "!",
Operator::Pipe => "|",
Operator::PipePipe => "||",
Operator::PipeEq => "|=",
Operator::Amp => "&",
Operator::AmpAmp => "&&",
Operator::AmpEq => "&=",
Operator::Caret => "^",
Operator::CaretEq => "^=",
}
}
}

@ -60,12 +60,43 @@ impl Iterator for Lexer {
'}' => self.token_ok(token::Kind::CBrace),
'[' => self.token_ok(token::Kind::OBracket),
']' => self.token_ok(token::Kind::CBracket),
'(' => self.token_ok(token::Kind::OParen),
')' => self.token_ok(token::Kind::CParen),
'=' if self.skip_if_match("=") => self.token_ok(token::Kind::EqEq),
'=' => self.token_ok(token::Kind::Eq),
'!' if self.skip_if_match("=") => self.token_ok(token::Kind::BangEq),
'!' => self.token_ok(token::Kind::Bang),
'>' if self.skip_if_match(">=") => self.token_ok(token::Kind::GtGtEq),
'>' if self.skip_if_match("=") => self.token_ok(token::Kind::GtEq),
'>' if self.skip_if_match("<") => self.token_ok(token::Kind::GtGt),
'>' => self.token_ok(token::Kind::Gt),
'<' if self.skip_if_match("<=") => self.token_ok(token::Kind::LtLtEq),
'<' if self.skip_if_match("=") => self.token_ok(token::Kind::LtEq),
'<' if self.skip_if_match("<") => self.token_ok(token::Kind::LtLt),
'<' => self.token_ok(token::Kind::Lt),
'|' if self.skip_if_match("|=") => self.token_ok(token::Kind::PipePipeEq),
'|' if self.skip_if_match("|") => self.token_ok(token::Kind::PipePipe),
'|' if self.skip_if_match("=") => self.token_ok(token::Kind::PipeEq),
'|' => self.token_ok(token::Kind::Pipe),
'&' if self.skip_if_match("&=") => self.token_ok(token::Kind::AmpAmpEq),
'&' if self.skip_if_match("&") => self.token_ok(token::Kind::AmpAmp),
'&' if self.skip_if_match("=") => self.token_ok(token::Kind::AmpEq),
'&' => self.token_ok(token::Kind::Amp),
'^' if self.skip_if_match("=") => self.token_ok(token::Kind::CaretEq),
'^' => self.token_ok(token::Kind::Caret),
'+' if self.skip_if_match("=") => self.token_ok(token::Kind::PlusEq),
'+' => self.token_ok(token::Kind::Plus),
'-' if self.skip_if_match("=") => self.token_ok(token::Kind::MinusEq),
'-' => self.token_ok(token::Kind::Minus),
'*' if self.skip_if_match("*=") => self.token_ok(token::Kind::AsteriskAsteriskEq),
'*' if self.skip_if_match("*") => self.token_ok(token::Kind::AsteriskAsterisk),
'*' if self.skip_if_match("=") => self.token_ok(token::Kind::AsteriskEq),
'*' => self.token_ok(token::Kind::Asterisk),
'/' if self.skip_if_match("=") => self.token_ok(token::Kind::SlashEq),
'/' => self.token_ok(token::Kind::Slash),
'%' if self.skip_if_match("=") => self.token_ok(token::Kind::PercentEq),
'%' => self.token_ok(token::Kind::Percent),
'#' => {

@ -29,15 +29,46 @@ pub enum Kind {
CBrace,
OBracket,
CBracket,
OParen,
CParen,
Comma,
Semi,
Eq,
EqEq,
Bang,
BangEq,
Gt,
GtGt,
GtEq,
GtGtEq,
Lt,
LtLt,
LtEq,
LtLtEq,
Amp,
AmpAmp,
AmpEq,
AmpAmpEq,
Pipe,
PipePipe,
PipeEq,
PipePipeEq,
Caret,
CaretEq,
Plus,
PlusEq,
Minus,
MinusEq,
Asterisk,
AsteriskAsterisk,
AsteriskEq,
AsteriskAsteriskEq,
Slash,
SlashEq,
Percent,
PercentEq,
DependKeyword,
IncludeKeyword,
@ -62,15 +93,46 @@ impl fmt::Display for Kind {
Kind::CBrace => "cbrace",
Kind::OBracket => "obracket",
Kind::CBracket => "cbracket",
Kind::OParen => "oparen",
Kind::CParen => "cparen",
Kind::Comma => "comma",
Kind::Semi => "semi",
Kind::Eq => "eq",
Kind::EqEq => "eqeq",
Kind::Bang => "bang",
Kind::BangEq => "bangeq",
Kind::Gt => "gt",
Kind::GtGt => "gtgt",
Kind::GtEq => "gteq",
Kind::GtGtEq => "gtgteq",
Kind::Lt => "lt",
Kind::LtLt => "ltlt",
Kind::LtEq => "lteq",
Kind::LtLtEq => "ltlteq",
Kind::Amp => "amp",
Kind::AmpAmp => "ampamp",
Kind::AmpEq => "ampeq",
Kind::AmpAmpEq => "ampampeq",
Kind::Pipe => "pipe",
Kind::PipePipe => "pipepipe",
Kind::PipeEq => "pipeeq",
Kind::PipePipeEq => "pipepipeeq",
Kind::Caret => "caret",
Kind::CaretEq => "careteq",
Kind::Plus => "plus",
Kind::PlusEq => "pluseq",
Kind::Minus => "minus",
Kind::MinusEq => "minuseq",
Kind::Asterisk => "asterisk",
Kind::AsteriskAsterisk => "asteriskasterisk",
Kind::AsteriskEq => "asteriskeq",
Kind::AsteriskAsteriskEq => "asteriskasteriskeq",
Kind::Slash => "slash",
Kind::SlashEq => "slasheq",
Kind::Percent => "percent",
Kind::PercentEq => "percenteq",
Kind::DependKeyword => "keyword",
Kind::IncludeKeyword => "keyword",

Loading…
Cancel
Save