mirror of
https://github.com/Noratrieb/ub.git
synced 2026-01-14 16:45:05 +01:00
why parser bad broken stupid
This commit is contained in:
parent
8a52378d4d
commit
83676704e1
4 changed files with 127 additions and 79 deletions
|
|
@ -17,10 +17,11 @@ pub fn parse(_str: &str, _file_name: PathBuf) -> Result<ast::File, ()> {
|
|||
|
||||
pub fn test() {
|
||||
let lexer = Token::lexer(
|
||||
"fn foo() {
|
||||
1 + 5;
|
||||
struct test {}
|
||||
}",
|
||||
"
|
||||
fn main() {
|
||||
if 1 { 5 + 5; }
|
||||
}
|
||||
",
|
||||
);
|
||||
let len = lexer.source().len();
|
||||
|
||||
|
|
|
|||
3
parser/src/main.rs
Normal file
3
parser/src/main.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
parser::test();
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@ use chumsky::{prelude::*, Stream};
|
|||
|
||||
use crate::{
|
||||
ast::{
|
||||
Assignment, BinOp, BinOpKind, Call, Expr, File, FnDecl, Item, Literal, NameTyPair, Stmt,
|
||||
StructDecl, Ty, TyKind, VarDecl,
|
||||
Assignment, BinOp, BinOpKind, Call, ElsePart, Expr, File, FnDecl, IfStmt, Item, Literal,
|
||||
NameTyPair, Stmt, StructDecl, Ty, TyKind, VarDecl,
|
||||
},
|
||||
lexer::Token,
|
||||
};
|
||||
|
|
@ -14,11 +14,10 @@ type Error<'src> = Simple<Token<'src>>;
|
|||
type Span = Range<usize>;
|
||||
|
||||
fn ident_parser<'src>() -> impl Parser<Token<'src>, String, Error = Error<'src>> + Clone {
|
||||
filter_map(|span, tok| match tok {
|
||||
Token::Ident(ident) => Ok(ident.to_owned()),
|
||||
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(tok))),
|
||||
})
|
||||
.labelled("identifier")
|
||||
let ident = select! {
|
||||
Token::Ident(ident) => ident.to_owned(),
|
||||
};
|
||||
ident.labelled("identifier")
|
||||
}
|
||||
|
||||
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>(
|
||||
item: impl Parser<Token<'src>, Item, Error = Error<'src>> + Clone,
|
||||
) -> impl Parser<Token<'src>, Stmt, Error = Error<'src>> + Clone {
|
||||
fn name_ty_pair_parser<'src>() -> impl Parser<Token<'src>, NameTyPair, 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()
|
||||
.then(ident_parser())
|
||||
.then_ignore(just(Token::Eq))
|
||||
|
|
@ -158,24 +182,49 @@ fn statement_parser<'src>(
|
|||
})
|
||||
});
|
||||
|
||||
var_decl
|
||||
.or(assignment)
|
||||
.or(expr_parser().map(|expr| Stmt::Expr(expr)))
|
||||
.or(item.clone().map(|item| Stmt::Item(item)))
|
||||
.then_ignore(just(Token::Semi))
|
||||
}
|
||||
let mut stmt = Recursive::declare();
|
||||
let if_stmt = recursive(|if_stmt| {
|
||||
just(Token::If)
|
||||
.ignore_then(expr_parser())
|
||||
.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
|
||||
{
|
||||
ident_parser()
|
||||
.then_ignore(just(Token::Colon))
|
||||
.then(ty_parser())
|
||||
.map_with_span(|(name, ty), span| NameTyPair { name, ty, span })
|
||||
}
|
||||
stmt.define(
|
||||
choice((
|
||||
var_decl,
|
||||
assignment,
|
||||
if_stmt,
|
||||
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 params = name_ty_pair_parser()
|
||||
|
|
@ -185,15 +234,13 @@ fn function_parser<'src>(
|
|||
.labelled("function arguments");
|
||||
|
||||
let ret_ty = just(Token::Arrow).ignore_then(ty_parser()).or_not();
|
||||
|
||||
just(Token::Fn)
|
||||
let function = just(Token::Fn)
|
||||
.map_with_span(|_, span| span)
|
||||
.then(name)
|
||||
.then(params)
|
||||
.then(ret_ty)
|
||||
.then(
|
||||
statement_parser(item)
|
||||
.repeated()
|
||||
stmt.repeated()
|
||||
.delimited_by(just(Token::BraceO), just(Token::BraceC)),
|
||||
)
|
||||
.map(|((((fn_span, name), params), ret_ty), body)| FnDecl {
|
||||
|
|
@ -203,28 +250,11 @@ fn function_parser<'src>(
|
|||
span: fn_span,
|
||||
body,
|
||||
})
|
||||
.labelled("function")
|
||||
}
|
||||
.labelled("function");
|
||||
|
||||
fn struct_parser<'src>() -> impl Parser<Token<'src>, StructDecl, Error = Error<'src>> + Clone {
|
||||
let name = just(Token::Struct).ignore_then(ident_parser());
|
||||
// ---- item
|
||||
|
||||
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| {
|
||||
function_parser(item)
|
||||
function
|
||||
.map(Item::FnDecl)
|
||||
.or(struct_parser().map(Item::StructDecl))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
source: parser/src/parser.rs
|
||||
assertion_line: 330
|
||||
expression: r
|
||||
---
|
||||
(
|
||||
Some(
|
||||
File {
|
||||
name: "parser__parser__tests",
|
||||
items: [],
|
||||
},
|
||||
),
|
||||
[],
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue