Lex tokens starting with !
(!important
and !=
)
This commit is contained in:
parent
3324a42f49
commit
adc94ffaa5
29
src/lexer.rs
29
src/lexer.rs
@ -2,7 +2,7 @@ use std::convert::TryFrom;
|
|||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
|
|
||||||
use crate::common::{Keyword, Pos, Symbol};
|
use crate::common::{Keyword, Op, Pos, Symbol};
|
||||||
use crate::selector::{Attribute, AttributeKind, Selector};
|
use crate::selector::{Attribute, AttributeKind, Selector};
|
||||||
use crate::units::Unit;
|
use crate::units::Unit;
|
||||||
use crate::{Token, TokenKind, Whitespace};
|
use crate::{Token, TokenKind, Whitespace};
|
||||||
@ -32,7 +32,7 @@ impl<'a> Iterator for Lexer<'a> {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
let kind: TokenKind = match self.buf.peek().unwrap_or(&'\0') {
|
let kind: TokenKind = match self.buf.peek().unwrap_or(&'\0') {
|
||||||
'a'..='z' | 'A'..='Z' => self.lex_ident(),
|
'a'..='z' | 'A'..='Z' | '-' | '_' => self.lex_ident(),
|
||||||
'@' => self.lex_at_rule(),
|
'@' => self.lex_at_rule(),
|
||||||
'0'..='9' => self.lex_num(),
|
'0'..='9' => self.lex_num(),
|
||||||
'$' => self.lex_variable(),
|
'$' => self.lex_variable(),
|
||||||
@ -63,6 +63,7 @@ impl<'a> Iterator for Lexer<'a> {
|
|||||||
self.pos.next_char();
|
self.pos.next_char();
|
||||||
self.lex_attr()
|
self.lex_attr()
|
||||||
}
|
}
|
||||||
|
'!' => self.lex_exclamation(),
|
||||||
'<' => symbol!(self, Lt),
|
'<' => symbol!(self, Lt),
|
||||||
'>' => symbol!(self, Gt),
|
'>' => symbol!(self, Gt),
|
||||||
'\0' => return None,
|
'\0' => return None,
|
||||||
@ -89,6 +90,30 @@ impl<'a> Lexer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lex_exclamation(&mut self) -> TokenKind {
|
||||||
|
self.buf.next();
|
||||||
|
self.pos.next_char();
|
||||||
|
macro_rules! assert_char {
|
||||||
|
($self:ident, $($char:literal)*) => {
|
||||||
|
$(
|
||||||
|
assert_eq!($char, $self.buf.next().expect("expected char").to_ascii_lowercase(), "expected keyword `important`");
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match self.buf.peek() {
|
||||||
|
Some('i') | Some('I') => {
|
||||||
|
self.buf.next();
|
||||||
|
assert_char!(self, 'm' 'p' 'o' 'r' 't' 'a' 'n' 't');
|
||||||
|
}
|
||||||
|
Some('=') => {
|
||||||
|
self.buf.next();
|
||||||
|
return TokenKind::Op(Op::NotEqual);
|
||||||
|
}
|
||||||
|
_ => todo!("expected either `i` or `=` after `!`"),
|
||||||
|
};
|
||||||
|
TokenKind::Keyword(Keyword::Important)
|
||||||
|
}
|
||||||
|
|
||||||
fn devour_whitespace(&mut self) {
|
fn devour_whitespace(&mut self) {
|
||||||
while let Some(c) = self.buf.peek() {
|
while let Some(c) = self.buf.peek() {
|
||||||
if !is_whitespace(*c) {
|
if !is_whitespace(*c) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user