why parser bad broken stupid

This commit is contained in:
nora 2022-03-25 22:10:38 +01:00
parent 8a52378d4d
commit 83676704e1
4 changed files with 127 additions and 79 deletions

View file

@ -17,10 +17,11 @@ pub fn parse(_str: &str, _file_name: PathBuf) -> Result<ast::File, ()> {
pub fn test() { pub fn test() {
let lexer = Token::lexer( let lexer = Token::lexer(
"fn foo() { "
1 + 5; fn main() {
struct test {} if 1 { 5 + 5; }
}", }
",
); );
let len = lexer.source().len(); let len = lexer.source().len();

3
parser/src/main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
parser::test();
}

View file

@ -4,8 +4,8 @@ use chumsky::{prelude::*, Stream};
use crate::{ use crate::{
ast::{ ast::{
Assignment, BinOp, BinOpKind, Call, Expr, File, FnDecl, Item, Literal, NameTyPair, Stmt, Assignment, BinOp, BinOpKind, Call, ElsePart, Expr, File, FnDecl, IfStmt, Item, Literal,
StructDecl, Ty, TyKind, VarDecl, NameTyPair, Stmt, StructDecl, Ty, TyKind, VarDecl,
}, },
lexer::Token, lexer::Token,
}; };
@ -14,11 +14,10 @@ type Error<'src> = Simple<Token<'src>>;
type Span = Range<usize>; type Span = Range<usize>;
fn ident_parser<'src>() -> impl Parser<Token<'src>, String, Error = Error<'src>> + Clone { fn ident_parser<'src>() -> impl Parser<Token<'src>, String, Error = Error<'src>> + Clone {
filter_map(|span, tok| match tok { let ident = select! {
Token::Ident(ident) => Ok(ident.to_owned()), Token::Ident(ident) => ident.to_owned(),
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(tok))), };
}) ident.labelled("identifier")
.labelled("identifier")
} }
fn ty_parser<'src>() -> impl Parser<Token<'src>, Ty, Error = Error<'src>> + Clone { fn ty_parser<'src>() -> impl Parser<Token<'src>, Ty, Error = Error<'src>> + Clone {
@ -131,9 +130,34 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
}) })
} }
fn statement_parser<'src>( fn name_ty_pair_parser<'src>() -> impl Parser<Token<'src>, NameTyPair, Error = Error<'src>> + Clone
item: impl Parser<Token<'src>, Item, Error = Error<'src>> + Clone, {
) -> impl Parser<Token<'src>, Stmt, Error = Error<'src>> + Clone { ident_parser()
.then_ignore(just(Token::Colon))
.then(ty_parser())
.map_with_span(|(name, ty), span| NameTyPair { name, ty, span })
}
fn struct_parser<'src>() -> impl Parser<Token<'src>, StructDecl, Error = Error<'src>> + Clone {
let name = just(Token::Struct).ignore_then(ident_parser());
let fields = name_ty_pair_parser()
.separated_by(just(Token::Comma))
.delimited_by(just(Token::BraceO), just(Token::BraceC));
name.then(fields)
.map(|(name, fields)| StructDecl {
name,
fields,
span: Default::default(),
})
.labelled("struct")
}
fn item_parser<'src>() -> impl Parser<Token<'src>, Item, Error = Error<'src>> + Clone {
recursive(|item| {
// ---- statement
let var_decl = ty_parser() let var_decl = ty_parser()
.then(ident_parser()) .then(ident_parser())
.then_ignore(just(Token::Eq)) .then_ignore(just(Token::Eq))
@ -158,24 +182,49 @@ fn statement_parser<'src>(
}) })
}); });
var_decl let mut stmt = Recursive::declare();
.or(assignment) let if_stmt = recursive(|if_stmt| {
.or(expr_parser().map(|expr| Stmt::Expr(expr))) just(Token::If)
.or(item.clone().map(|item| Stmt::Item(item))) .ignore_then(expr_parser())
.then_ignore(just(Token::Semi)) .then(
} stmt.clone()
.repeated()
.delimited_by(just(Token::BraceO), just(Token::BraceC)),
)
.then(
just(Token::Else).ignore_then(
if_stmt
.map(|if_stmt| ElsePart::ElseIf(Box::new(if_stmt)))
.or(stmt
.clone()
.repeated()
.delimited_by(just(Token::BraceO), just(Token::BraceC))
.map_with_span(ElsePart::Else))
.or_not(),
),
)
.map_with_span(|((cond, body), else_part), span| IfStmt {
cond,
body,
else_part,
span,
})
})
.map(Stmt::IfStmt);
fn name_ty_pair_parser<'src>() -> impl Parser<Token<'src>, NameTyPair, Error = Error<'src>> + Clone stmt.define(
{ choice((
ident_parser() var_decl,
.then_ignore(just(Token::Colon)) assignment,
.then(ty_parser()) if_stmt,
.map_with_span(|(name, ty), span| NameTyPair { name, ty, span }) expr_parser().map(Stmt::Expr),
} item.map(Stmt::Item),
))
.then_ignore(just(Token::Semi)),
);
// ---- function
fn function_parser<'src>(
item: impl Parser<Token<'src>, Item, Error = Error<'src>> + Clone,
) -> impl Parser<Token<'src>, FnDecl, Error = Error<'src>> + Clone {
let name = ident_parser(); let name = ident_parser();
let params = name_ty_pair_parser() let params = name_ty_pair_parser()
@ -185,15 +234,13 @@ fn function_parser<'src>(
.labelled("function arguments"); .labelled("function arguments");
let ret_ty = just(Token::Arrow).ignore_then(ty_parser()).or_not(); let ret_ty = just(Token::Arrow).ignore_then(ty_parser()).or_not();
let function = just(Token::Fn)
just(Token::Fn)
.map_with_span(|_, span| span) .map_with_span(|_, span| span)
.then(name) .then(name)
.then(params) .then(params)
.then(ret_ty) .then(ret_ty)
.then( .then(
statement_parser(item) stmt.repeated()
.repeated()
.delimited_by(just(Token::BraceO), just(Token::BraceC)), .delimited_by(just(Token::BraceO), just(Token::BraceC)),
) )
.map(|((((fn_span, name), params), ret_ty), body)| FnDecl { .map(|((((fn_span, name), params), ret_ty), body)| FnDecl {
@ -203,28 +250,11 @@ fn function_parser<'src>(
span: fn_span, span: fn_span,
body, body,
}) })
.labelled("function") .labelled("function");
}
fn struct_parser<'src>() -> impl Parser<Token<'src>, StructDecl, Error = Error<'src>> + Clone { // ---- item
let name = just(Token::Struct).ignore_then(ident_parser());
let fields = name_ty_pair_parser() function
.separated_by(just(Token::Comma))
.delimited_by(just(Token::BraceO), just(Token::BraceC));
name.then(fields)
.map(|(name, fields)| StructDecl {
name,
fields,
span: Default::default(),
})
.labelled("struct")
}
fn item_parser<'src>() -> impl Parser<Token<'src>, Item, Error = Error<'src>> + Clone {
recursive(|item| {
function_parser(item)
.map(Item::FnDecl) .map(Item::FnDecl)
.or(struct_parser().map(Item::StructDecl)) .or(struct_parser().map(Item::StructDecl))
}) })

View file

@ -0,0 +1,14 @@
---
source: parser/src/parser.rs
assertion_line: 330
expression: r
---
(
Some(
File {
name: "parser__parser__tests",
items: [],
},
),
[],
)