mirror of
https://github.com/Noratrieb/ub.git
synced 2026-01-17 01:55: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() {
|
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
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::{
|
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))
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -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