Parser refactoring WIP.
This commit is contained in:
parent
dbbcda638f
commit
a4b9b958e9
@ -71,16 +71,6 @@ pub fn parse_expression(input: &str) -> ParseResult<Expression> {
|
||||
(expression, diagnostics)
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub fn parse_let_statement(input: &str) -> ParseResult<Option<LetStatement>> {
|
||||
let mut parser = Parser::new(input);
|
||||
let mut diagnostics = Vec::new();
|
||||
diagnostics.append(&mut parser.advance());
|
||||
let (let_statement, mut ds) = parser.let_statement();
|
||||
diagnostics.append(&mut ds);
|
||||
(let_statement, diagnostics)
|
||||
}
|
||||
|
||||
macro_rules! matches_expression_first {
|
||||
( $token_kind : expr ) => {
|
||||
matches!(
|
||||
@ -96,12 +86,34 @@ macro_rules! matches_expression_first {
|
||||
};
|
||||
}
|
||||
|
||||
const EXPRESSION_FIRSTS: [TokenKind; 7] = [
|
||||
TokenKind::IntegerLiteral,
|
||||
TokenKind::DoubleLiteral,
|
||||
TokenKind::LongLiteral,
|
||||
TokenKind::String,
|
||||
TokenKind::Minus,
|
||||
TokenKind::SelfKw,
|
||||
TokenKind::Identifier,
|
||||
];
|
||||
|
||||
macro_rules! matches_statement_first {
|
||||
( $token_kind : expr ) => {
|
||||
matches!($token_kind, TokenKind::Let) || matches_expression_first!($token_kind)
|
||||
};
|
||||
}
|
||||
|
||||
const STATEMENT_FIRSTS: [TokenKind; 8] = {
|
||||
let mut firsts: [TokenKind; 8] = [TokenKind::Let; 8];
|
||||
|
||||
let mut i = 0;
|
||||
while i < EXPRESSION_FIRSTS.len() {
|
||||
firsts[i + 1] = EXPRESSION_FIRSTS[i];
|
||||
i += 1;
|
||||
}
|
||||
|
||||
firsts
|
||||
};
|
||||
|
||||
macro_rules! matches_type_use_first {
|
||||
( $token_kind: expr ) => {
|
||||
matches!($token_kind, TokenKind::LeftSquare | TokenKind::Identifier)
|
||||
@ -291,15 +303,6 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_current(&self) -> &Token {
|
||||
match &self.current {
|
||||
None => {
|
||||
panic!("Unexpected end of input");
|
||||
}
|
||||
Some(token) => token,
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_input(&self, start: usize, end: usize) -> &'a str {
|
||||
&self.input[start..end]
|
||||
}
|
||||
@ -322,7 +325,7 @@ impl<'a> Parser<'a> {
|
||||
let mut diagnostics = vec![];
|
||||
|
||||
while self.current.is_some() {
|
||||
let current = self.get_current();
|
||||
let current = self.current.as_ref().unwrap(); // loop checks for Some
|
||||
match current.kind() {
|
||||
TokenKind::Fn | TokenKind::Extern | TokenKind::Class => {
|
||||
let (_, mut ds) = self.module_level_declaration(
|
||||
@ -359,7 +362,16 @@ impl<'a> Parser<'a> {
|
||||
classes: &mut Vec<Class>,
|
||||
) -> ParseResult<()> {
|
||||
let mut diagnostics = Vec::new();
|
||||
let current = self.get_current();
|
||||
let current = match self.current.as_ref() {
|
||||
None => {
|
||||
diagnostics.push(Self::get_expected_but_found_eoi(
|
||||
&[TokenKind::Fn, TokenKind::Extern, TokenKind::Class],
|
||||
self.input.len(),
|
||||
));
|
||||
return ((), diagnostics);
|
||||
}
|
||||
Some(current) => current,
|
||||
};
|
||||
match current.kind() {
|
||||
TokenKind::Fn => {
|
||||
let (maybe_function, mut ds) = self.function();
|
||||
@ -512,7 +524,8 @@ impl<'a> Parser<'a> {
|
||||
let mut maybe_constructor: Option<Constructor> = None;
|
||||
|
||||
while self.current.is_some() && !self.peek_current(TokenKind::End) {
|
||||
match self.get_current().kind() {
|
||||
match self.current.as_ref().unwrap().kind() {
|
||||
// checked in loop
|
||||
TokenKind::Public => {
|
||||
let (_, mut ds) = self.public_class_member(
|
||||
&mut fields,
|
||||
@ -623,7 +636,7 @@ impl<'a> Parser<'a> {
|
||||
let mut diagnostics = Vec::new();
|
||||
|
||||
if self.current.is_some() {
|
||||
let current = self.get_current();
|
||||
let current = self.current.as_ref().unwrap(); // loop checks for Some
|
||||
return match current.kind() {
|
||||
TokenKind::LeftSquare => {
|
||||
diagnostics.append(&mut self.advance()); // [
|
||||
@ -685,7 +698,9 @@ impl<'a> Parser<'a> {
|
||||
let mut diagnostics = Vec::new();
|
||||
let mut generic_arguments: Vec<TypeUse> = vec![];
|
||||
|
||||
while self.current.is_some() && matches_type_use_first!(self.get_current().kind()) {
|
||||
while self.current.is_some()
|
||||
&& matches_type_use_first!(self.current.as_ref().unwrap().kind())
|
||||
{
|
||||
let (type_use, mut ds) = self.type_use();
|
||||
diagnostics.append(&mut ds);
|
||||
if let Some(type_use) = type_use {
|
||||
@ -736,7 +751,9 @@ impl<'a> Parser<'a> {
|
||||
let mut extends_list: Vec<TypeUse> = vec![];
|
||||
if self.current.is_some() && self.peek_current(TokenKind::Colon) {
|
||||
diagnostics.append(&mut self.advance()); // :
|
||||
while self.current.is_some() && matches_type_use_first!(self.get_current().kind()) {
|
||||
while self.current.is_some()
|
||||
&& matches_type_use_first!(self.current.as_ref().unwrap().kind())
|
||||
{
|
||||
let (maybe_type_use, mut ds) = self.type_use();
|
||||
diagnostics.append(&mut ds);
|
||||
if let Some(type_use) = maybe_type_use {
|
||||
@ -925,7 +942,17 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
fn statement(&mut self) -> ParseResult<Option<Statement>> {
|
||||
let current = self.get_current();
|
||||
let current = match self.current.as_ref() {
|
||||
None => {
|
||||
let mut ds = Diagnostics::new();
|
||||
ds.push(Self::get_expected_but_found_eoi(
|
||||
&STATEMENT_FIRSTS,
|
||||
self.input.len(),
|
||||
));
|
||||
return (None, ds);
|
||||
}
|
||||
Some(current) => current,
|
||||
};
|
||||
match current.kind() {
|
||||
TokenKind::Let => {
|
||||
let (maybe_let_statement, diagnostics) = self.let_statement();
|
||||
@ -1086,7 +1113,7 @@ impl<'a> Parser<'a> {
|
||||
diagnostics.append(&mut ds);
|
||||
|
||||
while self.current.is_some() {
|
||||
let current = self.get_current();
|
||||
let current = self.current.as_ref().unwrap();
|
||||
match current.kind() {
|
||||
TokenKind::Lt => {
|
||||
let previous_cloned = current.clone();
|
||||
@ -1142,7 +1169,7 @@ impl<'a> Parser<'a> {
|
||||
diagnostics.append(&mut ds);
|
||||
|
||||
while self.current.is_some() {
|
||||
let current = self.get_current();
|
||||
let current = self.current.as_ref().unwrap();
|
||||
match current.kind() {
|
||||
TokenKind::Plus => {
|
||||
diagnostics.append(&mut self.advance()); // plus
|
||||
@ -1187,7 +1214,7 @@ impl<'a> Parser<'a> {
|
||||
diagnostics.append(&mut ds);
|
||||
|
||||
while self.current.is_some() {
|
||||
let current = self.get_current();
|
||||
let current = self.current.as_ref().unwrap();
|
||||
match current.kind() {
|
||||
TokenKind::Star => {
|
||||
diagnostics.append(&mut self.advance()); // multiply
|
||||
@ -1246,7 +1273,7 @@ impl<'a> Parser<'a> {
|
||||
// first, collect all consecutive operators
|
||||
let mut operator_tokens = vec![];
|
||||
while self.current.is_some() {
|
||||
let current = self.get_current();
|
||||
let current = self.current.as_ref().unwrap();
|
||||
match current.kind() {
|
||||
TokenKind::Minus => {
|
||||
operator_tokens.push(current.clone()); // unfortunately necessary
|
||||
@ -1285,7 +1312,7 @@ impl<'a> Parser<'a> {
|
||||
diagnostics.append(&mut ds);
|
||||
|
||||
while self.current.is_some() {
|
||||
let current = self.get_current();
|
||||
let current = self.current.as_ref().unwrap();
|
||||
match current.kind() {
|
||||
TokenKind::LeftParentheses => {
|
||||
let (call, mut ds) = self.call(base);
|
||||
@ -1300,7 +1327,17 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
fn expression_base(&mut self) -> ParseResult<Expression> {
|
||||
let current = self.get_current();
|
||||
let current = match self.current.as_ref() {
|
||||
None => {
|
||||
let mut ds = Diagnostics::new();
|
||||
ds.push(Self::get_expected_but_found_eoi(
|
||||
&EXPRESSION_FIRSTS,
|
||||
self.input.len(),
|
||||
));
|
||||
return (todo!(), ds);
|
||||
}
|
||||
Some(current) => current,
|
||||
};
|
||||
let mut diagnostics = Vec::new();
|
||||
match current.kind() {
|
||||
TokenKind::IntegerLiteral => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user