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)
|
(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 {
|
macro_rules! matches_expression_first {
|
||||||
( $token_kind : expr ) => {
|
( $token_kind : expr ) => {
|
||||||
matches!(
|
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 {
|
macro_rules! matches_statement_first {
|
||||||
( $token_kind : expr ) => {
|
( $token_kind : expr ) => {
|
||||||
matches!($token_kind, TokenKind::Let) || matches_expression_first!($token_kind)
|
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 {
|
macro_rules! matches_type_use_first {
|
||||||
( $token_kind: expr ) => {
|
( $token_kind: expr ) => {
|
||||||
matches!($token_kind, TokenKind::LeftSquare | TokenKind::Identifier)
|
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 {
|
fn sample_input(&self, start: usize, end: usize) -> &'a str {
|
||||||
&self.input[start..end]
|
&self.input[start..end]
|
||||||
}
|
}
|
||||||
@ -322,7 +325,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut diagnostics = vec![];
|
let mut diagnostics = vec![];
|
||||||
|
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = self.get_current();
|
let current = self.current.as_ref().unwrap(); // loop checks for Some
|
||||||
match current.kind() {
|
match current.kind() {
|
||||||
TokenKind::Fn | TokenKind::Extern | TokenKind::Class => {
|
TokenKind::Fn | TokenKind::Extern | TokenKind::Class => {
|
||||||
let (_, mut ds) = self.module_level_declaration(
|
let (_, mut ds) = self.module_level_declaration(
|
||||||
@ -359,7 +362,16 @@ impl<'a> Parser<'a> {
|
|||||||
classes: &mut Vec<Class>,
|
classes: &mut Vec<Class>,
|
||||||
) -> ParseResult<()> {
|
) -> ParseResult<()> {
|
||||||
let mut diagnostics = Vec::new();
|
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() {
|
match current.kind() {
|
||||||
TokenKind::Fn => {
|
TokenKind::Fn => {
|
||||||
let (maybe_function, mut ds) = self.function();
|
let (maybe_function, mut ds) = self.function();
|
||||||
@ -512,7 +524,8 @@ impl<'a> Parser<'a> {
|
|||||||
let mut maybe_constructor: Option<Constructor> = None;
|
let mut maybe_constructor: Option<Constructor> = None;
|
||||||
|
|
||||||
while self.current.is_some() && !self.peek_current(TokenKind::End) {
|
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 => {
|
TokenKind::Public => {
|
||||||
let (_, mut ds) = self.public_class_member(
|
let (_, mut ds) = self.public_class_member(
|
||||||
&mut fields,
|
&mut fields,
|
||||||
@ -623,7 +636,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
|
|
||||||
if self.current.is_some() {
|
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() {
|
return match current.kind() {
|
||||||
TokenKind::LeftSquare => {
|
TokenKind::LeftSquare => {
|
||||||
diagnostics.append(&mut self.advance()); // [
|
diagnostics.append(&mut self.advance()); // [
|
||||||
@ -685,7 +698,9 @@ impl<'a> Parser<'a> {
|
|||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
let mut generic_arguments: Vec<TypeUse> = vec![];
|
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();
|
let (type_use, mut ds) = self.type_use();
|
||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
if let Some(type_use) = type_use {
|
if let Some(type_use) = type_use {
|
||||||
@ -736,7 +751,9 @@ impl<'a> Parser<'a> {
|
|||||||
let mut extends_list: Vec<TypeUse> = vec![];
|
let mut extends_list: Vec<TypeUse> = vec![];
|
||||||
if self.current.is_some() && self.peek_current(TokenKind::Colon) {
|
if self.current.is_some() && self.peek_current(TokenKind::Colon) {
|
||||||
diagnostics.append(&mut self.advance()); // :
|
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();
|
let (maybe_type_use, mut ds) = self.type_use();
|
||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
if let Some(type_use) = maybe_type_use {
|
if let Some(type_use) = maybe_type_use {
|
||||||
@ -925,7 +942,17 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&mut self) -> ParseResult<Option<Statement>> {
|
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() {
|
match current.kind() {
|
||||||
TokenKind::Let => {
|
TokenKind::Let => {
|
||||||
let (maybe_let_statement, diagnostics) = self.let_statement();
|
let (maybe_let_statement, diagnostics) = self.let_statement();
|
||||||
@ -1086,7 +1113,7 @@ impl<'a> Parser<'a> {
|
|||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
|
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = self.get_current();
|
let current = self.current.as_ref().unwrap();
|
||||||
match current.kind() {
|
match current.kind() {
|
||||||
TokenKind::Lt => {
|
TokenKind::Lt => {
|
||||||
let previous_cloned = current.clone();
|
let previous_cloned = current.clone();
|
||||||
@ -1142,7 +1169,7 @@ impl<'a> Parser<'a> {
|
|||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
|
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = self.get_current();
|
let current = self.current.as_ref().unwrap();
|
||||||
match current.kind() {
|
match current.kind() {
|
||||||
TokenKind::Plus => {
|
TokenKind::Plus => {
|
||||||
diagnostics.append(&mut self.advance()); // plus
|
diagnostics.append(&mut self.advance()); // plus
|
||||||
@ -1187,7 +1214,7 @@ impl<'a> Parser<'a> {
|
|||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
|
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = self.get_current();
|
let current = self.current.as_ref().unwrap();
|
||||||
match current.kind() {
|
match current.kind() {
|
||||||
TokenKind::Star => {
|
TokenKind::Star => {
|
||||||
diagnostics.append(&mut self.advance()); // multiply
|
diagnostics.append(&mut self.advance()); // multiply
|
||||||
@ -1246,7 +1273,7 @@ impl<'a> Parser<'a> {
|
|||||||
// first, collect all consecutive operators
|
// first, collect all consecutive operators
|
||||||
let mut operator_tokens = vec![];
|
let mut operator_tokens = vec![];
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = self.get_current();
|
let current = self.current.as_ref().unwrap();
|
||||||
match current.kind() {
|
match current.kind() {
|
||||||
TokenKind::Minus => {
|
TokenKind::Minus => {
|
||||||
operator_tokens.push(current.clone()); // unfortunately necessary
|
operator_tokens.push(current.clone()); // unfortunately necessary
|
||||||
@ -1285,7 +1312,7 @@ impl<'a> Parser<'a> {
|
|||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
|
|
||||||
while self.current.is_some() {
|
while self.current.is_some() {
|
||||||
let current = self.get_current();
|
let current = self.current.as_ref().unwrap();
|
||||||
match current.kind() {
|
match current.kind() {
|
||||||
TokenKind::LeftParentheses => {
|
TokenKind::LeftParentheses => {
|
||||||
let (call, mut ds) = self.call(base);
|
let (call, mut ds) = self.call(base);
|
||||||
@ -1300,7 +1327,17 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expression_base(&mut self) -> ParseResult<Expression> {
|
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();
|
let mut diagnostics = Vec::new();
|
||||||
match current.kind() {
|
match current.kind() {
|
||||||
TokenKind::IntegerLiteral => {
|
TokenKind::IntegerLiteral => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user