forked from katzen-cafe/iowo
lang: add pipelines and rename parser to lst_parser
This commit is contained in:
parent
db2643359c
commit
30f17773a8
18 changed files with 108 additions and 47 deletions
|
@ -1,2 +1,2 @@
|
|||
#![feature(type_alias_impl_trait, lint_reasons)]
|
||||
pub mod parser;
|
||||
pub mod lst_parser;
|
||||
|
|
|
@ -134,8 +134,8 @@ pub(crate) struct CompletedMarker {
|
|||
}
|
||||
|
||||
impl CompletedMarker {
|
||||
pub(crate) fn precede(self, p: &mut Parser<'_, '_>) -> Marker {
|
||||
let new_pos = p.start("new_pos");
|
||||
pub(crate) fn precede(self, p: &mut Parser<'_, '_>, name: &str) -> Marker {
|
||||
let new_pos = p.start(name);
|
||||
|
||||
match &mut p.events[self.pos] {
|
||||
Event::Start { forward_parent, .. } => {
|
|
@ -1,6 +1,7 @@
|
|||
use crate::parser::syntax_kind::SyntaxKind;
|
||||
use crate::lst_parser::syntax_kind::SyntaxKind;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SyntaxError {
|
||||
Expected(Vec<SyntaxKind>),
|
||||
PipelineNeedsSink,
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::parser::syntax_kind::SyntaxKind;
|
||||
use crate::lst_parser::syntax_kind::SyntaxKind;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Event {
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use crate::parser::syntax_kind::SyntaxKind::*;
|
||||
use crate::lst_parser::syntax_kind::SyntaxKind::*;
|
||||
|
||||
use super::{
|
||||
input::Input,
|
||||
|
@ -14,7 +14,7 @@ mod expression;
|
|||
pub fn source_file(p: &mut Parser) {
|
||||
let root = p.start("root");
|
||||
|
||||
expression::expression(p);
|
||||
expression::expression(p, false);
|
||||
p.eat_succeeding_ws();
|
||||
|
||||
root.complete(p, ROOT);
|
81
crates/lang/src/lst_parser/grammar/expression.rs
Normal file
81
crates/lang/src/lst_parser/grammar/expression.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
use crate::lst_parser::{error::SyntaxError, syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
||||
|
||||
use self::{collection::collection, instruction::instr, lit::literal, pipeline::PIPES};
|
||||
|
||||
mod collection;
|
||||
mod instruction;
|
||||
mod lit;
|
||||
mod pipeline {
|
||||
use enumset::enum_set;
|
||||
|
||||
use crate::lst_parser::{
|
||||
error::SyntaxError,
|
||||
syntax_kind::{SyntaxKind::*, TokenSet},
|
||||
CompletedMarker, Parser,
|
||||
};
|
||||
|
||||
use super::expression;
|
||||
|
||||
pub fn pipeline(p: &mut Parser, start_expr: CompletedMarker) -> Option<CompletedMarker> {
|
||||
if !pipe(p) {
|
||||
return Some(start_expr);
|
||||
}
|
||||
let pipeline_marker = start_expr.precede(p, "pipeline_start");
|
||||
|
||||
loop {
|
||||
if expression(p, true).is_none() {
|
||||
return Some(pipeline_marker.complete_err(p, SyntaxError::PipelineNeedsSink));
|
||||
}
|
||||
if !pipe(p) {
|
||||
return Some(pipeline_marker.complete(p, PIPELINE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const PIPES: TokenSet = enum_set!(PIPE | MAPPING_PIPE | NULL_PIPE);
|
||||
|
||||
fn pipe(p: &mut Parser) -> bool {
|
||||
if PIPES.contains(p.current()) {
|
||||
p.do_bump();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expression(p: &mut Parser, in_pipe: bool) -> Option<CompletedMarker> {
|
||||
let expr = p.start("expr");
|
||||
|
||||
if atom(p).or_else(|| instr(p)).is_none() {
|
||||
expr.abandon(p);
|
||||
return None;
|
||||
}
|
||||
|
||||
let r = expr.complete(p, EXPR);
|
||||
|
||||
if PIPES.contains(p.current()) && !in_pipe {
|
||||
pipeline::pipeline(p, r)
|
||||
} else {
|
||||
Some(r)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn atom(p: &mut Parser) -> Option<CompletedMarker> {
|
||||
literal(p)
|
||||
.or_else(|| collection(p))
|
||||
.or_else(|| parenthesized_expr(p))
|
||||
}
|
||||
|
||||
pub fn parenthesized_expr(p: &mut Parser) -> Option<CompletedMarker> {
|
||||
if p.eat(L_PAREN) {
|
||||
let par_expr = p.start("parenthesized");
|
||||
expression(p, false);
|
||||
if !p.eat(R_PAREN) {
|
||||
return Some(par_expr.complete_err(p, SyntaxError::Expected(vec![R_PAREN])));
|
||||
}
|
||||
|
||||
return Some(par_expr.complete(p, PARENTHESIZED_EXPR));
|
||||
}
|
||||
None
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use enumset::enum_set;
|
||||
|
||||
use crate::parser::{
|
||||
use crate::lst_parser::{
|
||||
syntax_kind::{SyntaxKind::*, TokenSet},
|
||||
CompletedMarker, Parser,
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
use crate::parser::{
|
||||
use crate::lst_parser::{
|
||||
error::SyntaxError,
|
||||
grammar::expression::{atom, expression},
|
||||
CompletedMarker, Marker, Parser,
|
||||
|
@ -36,7 +36,7 @@ fn attr(p: &mut Parser) -> Option<CompletedMarker> {
|
|||
|
||||
// TODO: handle failed expr parser too
|
||||
let attr_value = p.start("attr_value");
|
||||
let _ = expression(p);
|
||||
let _ = expression(p, false);
|
||||
attr_value.complete(p, ATTR_VALUE);
|
||||
Some(attr_start.complete(p, ATTR))
|
||||
} else {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::parser::{
|
||||
use crate::lst_parser::{
|
||||
error::SyntaxError, grammar::expression::atom, CompletedMarker, Marker, Parser, SyntaxKind::*,
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,8 @@ pub fn vec_matrix_list(p: &mut Parser) -> CompletedMarker {
|
|||
assert!(p.eat(L_BRACK));
|
||||
let row_start = p.start("matrix_row_start");
|
||||
if let Some(item) = atom(p) {
|
||||
item.precede(p).complete(p, COLLECTION_ITEM);
|
||||
item.precede(p, "coll_item_start")
|
||||
.complete(p, COLLECTION_ITEM);
|
||||
|
||||
if p.at(COMMA) {
|
||||
row_start.abandon(p);
|
||||
|
@ -27,7 +28,8 @@ fn finish_list(p: &mut Parser, list_start: Marker) -> CompletedMarker {
|
|||
loop {
|
||||
if p.eat(COMMA) {
|
||||
if let Some(item) = atom(p) {
|
||||
item.precede(p).complete(p, COLLECTION_ITEM);
|
||||
item.precede(p, "coll_item_start")
|
||||
.complete(p, COLLECTION_ITEM);
|
||||
} else if p.eat(R_BRACK) {
|
||||
return list_start.complete(p, LIST);
|
||||
}
|
||||
|
@ -43,7 +45,8 @@ fn finish_mat_or_vec(p: &mut Parser, coll_start: Marker, mut row_start: Marker)
|
|||
let mut row_item_count = 1;
|
||||
loop {
|
||||
if let Some(item) = atom(p) {
|
||||
item.precede(p).complete(p, COLLECTION_ITEM);
|
||||
item.precede(p, "coll_item_start")
|
||||
.complete(p, COLLECTION_ITEM);
|
||||
row_item_count += 1;
|
||||
} else if p.at(SEMICOLON) {
|
||||
is_matrix = true;
|
|
@ -1,4 +1,4 @@
|
|||
use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
||||
use crate::lst_parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
||||
|
||||
use super::{atom, lit::literal};
|
||||
|
||||
|
@ -29,6 +29,6 @@ fn instr_params(p: &mut Parser) {
|
|||
if let Some(start) = atom(p) {
|
||||
while atom(p).is_some() {}
|
||||
|
||||
start.precede(p).complete(p, INSTR_PARAMS);
|
||||
start.precede(p, "params_start").complete(p, INSTR_PARAMS);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use enumset::enum_set;
|
||||
use indoc::indoc;
|
||||
|
||||
use crate::parser::{
|
||||
use crate::lst_parser::{
|
||||
grammar::check_parser,
|
||||
syntax_kind::{SyntaxKind::*, TokenSet},
|
||||
CompletedMarker, Parser,
|
|
@ -1,4 +1,4 @@
|
|||
use crate::parser::syntax_kind::SyntaxKind;
|
||||
use crate::lst_parser::syntax_kind::SyntaxKind;
|
||||
|
||||
pub struct Input<'src, 'toks> {
|
||||
raw: &'toks Vec<(SyntaxKind, &'src str)>,
|
|
@ -1,7 +1,7 @@
|
|||
use rowan::{GreenNode, GreenNodeBuilder, GreenNodeData, GreenTokenData, Language, NodeOrToken};
|
||||
use std::mem;
|
||||
|
||||
use crate::parser::syntax_kind::{Lang, SyntaxKind};
|
||||
use crate::lst_parser::syntax_kind::{Lang, SyntaxKind};
|
||||
|
||||
use super::{error::SyntaxError, events::Event};
|
||||
|
|
@ -92,6 +92,7 @@ pub enum SyntaxKind {
|
|||
MAPPING_PIPE,
|
||||
#[token("!|")]
|
||||
NULL_PIPE,
|
||||
PIPELINE,
|
||||
#[token("=")]
|
||||
EQ,
|
||||
#[token(":")]
|
|
@ -1,7 +1,7 @@
|
|||
use clap::Parser;
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use lang::parser::{self, grammar, input, output::Output, syntax_kind};
|
||||
use lang::lst_parser::{self, grammar, input, output::Output, syntax_kind};
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
|
@ -16,7 +16,7 @@ fn main() {
|
|||
|
||||
let toks = dbg!(syntax_kind::lex(&f));
|
||||
let input = input::Input::new(&toks);
|
||||
let mut parser = parser::Parser::new(input);
|
||||
let mut parser = lst_parser::Parser::new(input);
|
||||
|
||||
grammar::source_file(&mut parser);
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
||||
|
||||
use self::{collection::collection, instruction::instr, lit::literal};
|
||||
|
||||
mod collection;
|
||||
mod instruction;
|
||||
mod lit;
|
||||
|
||||
pub fn expression(p: &mut Parser) -> Option<CompletedMarker> {
|
||||
let expr = p.start("expr");
|
||||
|
||||
if atom(p).or_else(|| instr(p)).is_none() {
|
||||
expr.abandon(p);
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(expr.complete(p, EXPR))
|
||||
}
|
||||
|
||||
pub fn atom(p: &mut Parser) -> Option<CompletedMarker> {
|
||||
literal(p).or_else(|| collection(p))
|
||||
}
|
|
@ -1,4 +1 @@
|
|||
generator | {
|
||||
foo,
|
||||
bar
|
||||
} |
|
||||
meow 1 (3 | add 1)
|
||||
|
|
Loading…
Reference in a new issue