lang: matrix parser!

This commit is contained in:
Schrottkatze 2024-04-24 19:37:52 +02:00
parent 86b1481943
commit 2bea3994c2
Signed by: schrottkatze
SSH key fingerprint: SHA256:hXb3t1vINBFCiDCmhRABHX5ocdbLiKyCdKI4HK2Rbbc
6 changed files with 144 additions and 12 deletions

View file

@ -94,6 +94,7 @@ impl Marker {
bomb: DropBomb::new("Marker must be completed or abandoned"), bomb: DropBomb::new("Marker must be completed or abandoned"),
} }
} }
pub(crate) fn complete(mut self, p: &mut Parser<'_, '_>, kind: SyntaxKind) -> CompletedMarker { pub(crate) fn complete(mut self, p: &mut Parser<'_, '_>, kind: SyntaxKind) -> CompletedMarker {
self.bomb.defuse(); self.bomb.defuse();
match &mut p.events[self.pos] { match &mut p.events[self.pos] {
@ -108,6 +109,11 @@ impl Marker {
} }
} }
pub(crate) fn complete_err(mut self, p: &mut Parser, kind: SyntaxError) -> CompletedMarker {
p.errors.push(kind);
self.complete(p, SyntaxKind::PARSE_ERR)
}
pub(crate) fn abandon(mut self, p: &mut Parser<'_, '_>) { pub(crate) fn abandon(mut self, p: &mut Parser<'_, '_>) {
self.bomb.defuse(); self.bomb.defuse();
if self.pos == p.events.len() - 1 { if self.pos == p.events.len() - 1 {

View file

@ -1,14 +1,62 @@
use crate::parser::{syntax_kind::SyntaxKind::*, Parser}; use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
use self::{instruction::instr, lit::literal}; use self::{collection::collection, instruction::instr, lit::literal};
mod instruction; mod instruction;
mod lit; mod lit;
mod collection {
use enumset::enum_set;
pub fn expression(p: &mut Parser) { use crate::parser::{
syntax_kind::{SyntaxKind::*, TokenSet},
CompletedMarker, Parser,
};
use self::{attr_set::attr_set, matrix::matrix, vec::vec};
const COLLECTION_START: TokenSet = enum_set!(MAT_KW | L_BRACK | L_BRACE);
pub fn collection(p: &mut Parser) -> Option<CompletedMarker> {
if !COLLECTION_START.contains(p.current()) {
return None;
}
Some(match p.current() {
MAT_KW => matrix(p),
L_BRACK => vec(p),
L_BRACE => attr_set(p),
_ => unreachable!(),
})
}
mod matrix;
mod vec {
use crate::parser::{CompletedMarker, Parser};
pub fn vec(p: &mut Parser) -> CompletedMarker {
todo!()
}
}
mod attr_set {
use crate::parser::{CompletedMarker, Parser};
pub fn attr_set(p: &mut Parser) -> CompletedMarker {
todo!()
}
}
}
pub fn expression(p: &mut Parser) -> Option<CompletedMarker> {
let expr = p.start(); let expr = p.start();
instr(p); if atom(p).or_else(|| instr(p)).is_none() {
expr.abandon(p);
expr.complete(p, EXPR); return None;
}
Some(expr.complete(p, EXPR))
}
pub fn atom(p: &mut Parser) -> Option<CompletedMarker> {
literal(p).or_else(|| collection(p))
} }

View file

@ -0,0 +1,69 @@
use crate::parser::{
error::SyntaxError,
grammar::expression::{self, expression},
syntax_kind::SyntaxKind::*,
CompletedMarker, Marker, Parser,
};
pub fn matrix(p: &mut Parser) -> CompletedMarker {
let matrix = p.start();
p.eat(MAT_KW);
if !p.eat(PAT_DIMENSIONS) {
eprintln!("TODO (as eprintln so i dont forget): improve recovery algorithms");
return matrix.complete_err(p, SyntaxError::Expected(vec![PAT_DIMENSIONS]));
}
matrix_body(p);
matrix.complete(p, MATRIX)
}
fn matrix_body(p: &mut Parser) {
let mat_body = p.start();
if !p.eat(L_BRACK) {
mat_body.complete_err(p, SyntaxError::Expected(vec![MAT_BODY]));
return ();
}
let mut going = true;
let mut mat_row = p.start();
let mut row_items = 0;
while going {
let mat_item = p.start();
if expression(p).is_some() {
mat_item.complete(p, MAT_ITEM);
row_items += 1;
match p.current() {
COMMA => p.do_bump(),
SEMICOLON => {
mat_row.complete(p, MAT_ROW);
mat_row = p.start();
p.do_bump();
row_items = 0;
}
R_BRACK => going = false,
_ => {
let err = p.start();
p.do_bump();
err.complete_err(p, SyntaxError::Expected(vec![COMMA, SEMICOLON, R_BRACK]));
}
};
} else if p.at(R_BRACK) {
going = false;
} else {
let err = p.start();
p.do_bump();
err.complete_err(p, SyntaxError::Expected(vec![EXPR, R_BRACK]));
}
}
if row_items != 0 {
mat_row.complete(p, MAT_ROW);
} else {
mat_row.abandon(p);
}
p.eat(R_BRACK);
mat_body.complete(p, MAT_BODY);
}

View file

@ -1,14 +1,18 @@
use crate::parser::{syntax_kind::SyntaxKind::*, Parser}; use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
use super::lit::literal; use super::lit::literal;
pub fn instr(p: &mut Parser) { pub fn instr(p: &mut Parser) -> Option<CompletedMarker> {
if !p.at(IDENT) {
return None;
}
let instr = p.start(); let instr = p.start();
instr_name(p); instr_name(p);
instr_params(p); instr_params(p);
instr.complete(p, INSTR); Some(instr.complete(p, INSTR))
} }
fn instr_name(p: &mut Parser) { fn instr_name(p: &mut Parser) {

View file

@ -34,9 +34,11 @@ pub enum SyntaxKind {
#[regex(r#""([^"\\]|\\["\\bnfrt]|u[a-fA-F0-9]{4})*""#)] #[regex(r#""([^"\\]|\\["\\bnfrt]|u[a-fA-F0-9]{4})*""#)]
STRING, STRING,
MATRIX, MATRIX,
MAT_BODY,
MAT_ROW,
MAT_ITEM,
DECL, DECL,
LIST, LIST,
MAT_BODY,
PARENTHESIZED_EXPR, PARENTHESIZED_EXPR,
EXPR, EXPR,
LITERAL, LITERAL,
@ -45,9 +47,9 @@ pub enum SyntaxKind {
#[token(")")] #[token(")")]
R_PAREN, R_PAREN,
#[token("{")] #[token("{")]
L_CURLY, L_BRACE,
#[token("}")] #[token("}")]
R_CURLY, R_BRACE,
#[token("[")] #[token("[")]
L_BRACK, L_BRACK,
#[token("]")] #[token("]")]

View file

@ -1 +1,4 @@
hello world test 1.5 42 69 "gay" mat 2x2 [
1, 2;
3, 4
]