cl-parser: break parser into inline module

This commit is contained in:
John 2024-02-29 20:43:40 -06:00
parent cc281fc6ab
commit ab17ebbadc

View File

@ -5,17 +5,11 @@
//! [1]: https://git.soft.fish/j/Conlang/src/branch/main/grammar.ebnf //! [1]: https://git.soft.fish/j/Conlang/src/branch/main/grammar.ebnf
#![feature(decl_macro)] #![feature(decl_macro)]
pub use parser::Parser;
use cl_structures::span::*; use cl_structures::span::*;
use cl_token::*; use cl_token::*;
use crate::error::{
Error,
ErrorKind::{self, *},
PResult, Parsing,
};
use cl_ast::*;
use conlang::lexer::Lexer;
pub mod error { pub mod error {
use super::*; use super::*;
@ -228,19 +222,28 @@ pub mod error {
} }
} }
pub mod parser {
use super::*;
use crate::error::{
Error,
ErrorKind::{self, *},
PResult, Parsing,
};
use cl_ast::*;
use conlang::lexer::Lexer;
/// Parses a sequence of [Tokens](Token) into an [AST](cl_ast) /// Parses a sequence of [Tokens](Token) into an [AST](cl_ast)
pub struct Parser<'t> { pub struct Parser<'t> {
/// Lazy tokenizer /// Lazy tokenizer
lexer: Lexer<'t>, lexer: Lexer<'t>,
/// Look-ahead buffer /// Look-ahead buffer
next: Option<Token>, next: Option<Token>,
/// The location of the current token /// The location of the current token
loc: Loc, loc: Loc,
} }
/// Basic parser functionality /// Basic parser functionality
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
pub fn new(lexer: Lexer<'t>) -> Self { pub fn new(lexer: Lexer<'t>) -> Self {
Self { loc: Loc::from(&lexer), lexer, next: None } Self { loc: Loc::from(&lexer), lexer, next: None }
} }
@ -310,39 +313,39 @@ impl<'t> Parser<'t> {
pub fn match_kw(&mut self, pat: Keyword, while_parsing: Parsing) -> PResult<Token> { pub fn match_kw(&mut self, pat: Keyword, while_parsing: Parsing) -> PResult<Token> {
self.match_type(Type::Keyword(pat), while_parsing) self.match_type(Type::Keyword(pat), while_parsing)
} }
} }
// the three matched delimiter pairs // the three matched delimiter pairs
/// Square brackets: `[` `]` /// Square brackets: `[` `]`
const BRACKETS: (Type, Type) = (Type::LBrack, Type::RBrack); const BRACKETS: (Type, Type) = (Type::LBrack, Type::RBrack);
/// Curly braces: `{` `}` /// Curly braces: `{` `}`
const CURLIES: (Type, Type) = (Type::LCurly, Type::RCurly); const CURLIES: (Type, Type) = (Type::LCurly, Type::RCurly);
/// Parentheses: `(` `)` /// Parentheses: `(` `)`
const PARENS: (Type, Type) = (Type::LParen, Type::RParen); const PARENS: (Type, Type) = (Type::LParen, Type::RParen);
/// Parses constructions of the form `delim.0 f delim.1` (i.e. `(` `foobar` `)`) /// Parses constructions of the form `delim.0 f delim.1` (i.e. `(` `foobar` `)`)
const fn delim<'t, T>( const fn delim<'t, T>(
f: impl Fn(&mut Parser<'t>) -> PResult<T>, f: impl Fn(&mut Parser<'t>) -> PResult<T>,
delim: (Type, Type), delim: (Type, Type),
while_parsing: Parsing, while_parsing: Parsing,
) -> impl Fn(&mut Parser<'t>) -> PResult<T> { ) -> impl Fn(&mut Parser<'t>) -> PResult<T> {
move |parser| { move |parser| {
parser.match_type(delim.0, while_parsing)?; parser.match_type(delim.0, while_parsing)?;
let out = f(parser)?; let out = f(parser)?;
parser.match_type(delim.1, while_parsing)?; parser.match_type(delim.1, while_parsing)?;
Ok(out) Ok(out)
} }
} }
/// Parses constructions of the form `(f sep ~until)*` /// Parses constructions of the form `(f sep ~until)*`
/// ///
/// where `~until` is a negative lookahead assertion /// where `~until` is a negative lookahead assertion
const fn sep<'t, T>( const fn sep<'t, T>(
f: impl Fn(&mut Parser<'t>) -> PResult<T>, f: impl Fn(&mut Parser<'t>) -> PResult<T>,
sep: Type, sep: Type,
until: Type, until: Type,
while_parsing: Parsing, while_parsing: Parsing,
) -> impl Fn(&mut Parser<'t>) -> PResult<Vec<T>> { ) -> impl Fn(&mut Parser<'t>) -> PResult<Vec<T>> {
move |parser| { move |parser| {
let mut args = vec![]; let mut args = vec![];
while until != parser.peek_type(while_parsing)? { while until != parser.peek_type(while_parsing)? {
@ -354,17 +357,17 @@ const fn sep<'t, T>(
} }
Ok(args) Ok(args)
} }
} }
/// Parses constructions of the form `(f ~until)*` /// Parses constructions of the form `(f ~until)*`
/// ///
/// where `~until` is a negative lookahead assertion /// where `~until` is a negative lookahead assertion
#[allow(dead_code)] #[allow(dead_code)]
const fn rep<'t, T>( const fn rep<'t, T>(
f: impl Fn(&mut Parser<'t>) -> PResult<T>, f: impl Fn(&mut Parser<'t>) -> PResult<T>,
until: Type, until: Type,
while_parsing: Parsing, while_parsing: Parsing,
) -> impl Fn(&mut Parser<'t>) -> PResult<Vec<T>> { ) -> impl Fn(&mut Parser<'t>) -> PResult<Vec<T>> {
move |parser| { move |parser| {
let mut out = vec![]; let mut out = vec![];
while until != parser.peek_type(while_parsing)? { while until != parser.peek_type(while_parsing)? {
@ -372,10 +375,10 @@ const fn rep<'t, T>(
} }
Ok(out) Ok(out)
} }
} }
/// Expands to a pattern which matches item-like [Token] [Type]s /// Expands to a pattern which matches item-like [Token] [Type]s
macro item_like() { macro item_like() {
Type::Hash Type::Hash
| Type::Keyword( | Type::Keyword(
Keyword::Pub Keyword::Pub
@ -388,10 +391,10 @@ macro item_like() {
| Keyword::Enum | Keyword::Enum
| Keyword::Impl, | Keyword::Impl,
) )
} }
/// Top level parsing /// Top level parsing
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// Parses a [File] /// Parses a [File]
pub fn file(&mut self) -> PResult<File> { pub fn file(&mut self) -> PResult<File> {
let mut items = vec![]; let mut items = vec![];
@ -469,10 +472,10 @@ impl<'t> Parser<'t> {
pub fn expr(&mut self) -> PResult<Expr> { pub fn expr(&mut self) -> PResult<Expr> {
self.expr_from(Self::exprkind) self.expr_from(Self::exprkind)
} }
} }
/// Attribute parsing /// Attribute parsing
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// Parses an [attribute set](Attrs) /// Parses an [attribute set](Attrs)
pub fn attributes(&mut self) -> PResult<Attrs> { pub fn attributes(&mut self) -> PResult<Attrs> {
if self.match_type(Type::Hash, Parsing::Attrs).is_err() { if self.match_type(Type::Hash, Parsing::Attrs).is_err() {
@ -504,10 +507,10 @@ impl<'t> Parser<'t> {
_ => MetaKind::Plain, _ => MetaKind::Plain,
}) })
} }
} }
/// Item parsing /// Item parsing
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// Parses an [ItemKind] /// Parses an [ItemKind]
/// ///
/// See also: [Parser::item] /// See also: [Parser::item]
@ -704,10 +707,10 @@ impl<'t> Parser<'t> {
}; };
Ok(Mutability::Not) Ok(Mutability::Not)
} }
} }
/// # Type parsing /// # Type parsing
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// Parses a [TyKind] /// Parses a [TyKind]
/// ///
/// See also: [Parser::ty] /// See also: [Parser::ty]
@ -773,22 +776,22 @@ impl<'t> Parser<'t> {
}, },
}) })
} }
} }
/// Expands to a pattern which matches literal-like [Type]s /// Expands to a pattern which matches literal-like [Type]s
macro literal_like() { macro literal_like() {
Type::Keyword(Keyword::True | Keyword::False) Type::Keyword(Keyword::True | Keyword::False)
| Type::String | Type::String
| Type::Character | Type::Character
| Type::Integer | Type::Integer
| Type::Float | Type::Float
} }
/// Expands to a pattern which matches path-like [token Types](Type) /// Expands to a pattern which matches path-like [token Types](Type)
macro path_like() { macro path_like() {
Type::Keyword(Keyword::Super | Keyword::SelfKw) | Type::Identifier | Type::ColonColon Type::Keyword(Keyword::Super | Keyword::SelfKw) | Type::Identifier | Type::ColonColon
} }
/// # Path parsing /// # Path parsing
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// [PathPart] = `super` | `self` | [Identifier] /// [PathPart] = `super` | `self` | [Identifier]
pub fn path_part(&mut self) -> PResult<PathPart> { pub fn path_part(&mut self) -> PResult<PathPart> {
const PARSING: Parsing = Parsing::PathPart; const PARSING: Parsing = Parsing::PathPart;
@ -809,10 +812,10 @@ impl<'t> Parser<'t> {
_ => panic!("Expected token data for {tok:?}"), _ => panic!("Expected token data for {tok:?}"),
} }
} }
} }
/// # Statement parsing /// # Statement parsing
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// Parses a [StmtKind] /// Parses a [StmtKind]
/// ///
/// See also: [Parser::stmt] /// See also: [Parser::stmt]
@ -844,9 +847,9 @@ impl<'t> Parser<'t> {
}, },
}) })
} }
} }
macro binary($($name:ident {$lower:ident, $op:ident})*) { macro binary($($name:ident {$lower:ident, $op:ident})*) {
$(pub fn $name(&mut self) -> PResult<ExprKind> { $(pub fn $name(&mut self) -> PResult<ExprKind> {
let head = self.expr_from(Self::$lower)?; let head = self.expr_from(Self::$lower)?;
let mut tail = vec![]; let mut tail = vec![];
@ -863,8 +866,8 @@ macro binary($($name:ident {$lower:ident, $op:ident})*) {
Ok(Binary { head: head.into(), tail }.into()) Ok(Binary { head: head.into(), tail }.into())
})* })*
} }
/// # Expression parsing /// # Expression parsing
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// Parses an [ExprKind] /// Parses an [ExprKind]
/// ///
/// See also: [Parser::expr], [Parser::exprkind_primary] /// See also: [Parser::expr], [Parser::exprkind_primary]
@ -1085,10 +1088,10 @@ impl<'t> Parser<'t> {
_ => Ok(Group { expr: first.into() }.into()), _ => Ok(Group { expr: first.into() }.into()),
} }
} }
} }
/// ## Subexpressions /// ## Subexpressions
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// [Literal] = [String](Type::String) | [Character](Type::Character) /// [Literal] = [String](Type::String) | [Character](Type::Character)
/// | [Float](Type::Float) (TODO) | [Integer](Type::Integer) | `true` | `false` /// | [Float](Type::Float) (TODO) | [Integer](Type::Integer) | `true` | `false`
pub fn literal(&mut self) -> PResult<Literal> { pub fn literal(&mut self) -> PResult<Literal> {
@ -1127,11 +1130,15 @@ impl<'t> Parser<'t> {
/// [Block] = `{` [Stmt]* `}` /// [Block] = `{` [Stmt]* `}`
pub fn block(&mut self) -> PResult<Block> { pub fn block(&mut self) -> PResult<Block> {
const PARSING: Parsing = Parsing::Block; const PARSING: Parsing = Parsing::Block;
Ok(Block { stmts: delim(rep(Self::stmt, CURLIES.1, PARSING), CURLIES, PARSING)(self)? }) Ok(
Block {
stmts: delim(rep(Self::stmt, CURLIES.1, PARSING), CURLIES, PARSING)(self)?,
},
)
} }
} }
/// ## Control flow subexpressions /// ## Control flow subexpressions
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
/// [Break] = `break` [Expr]? /// [Break] = `break` [Expr]?
pub fn parse_break(&mut self) -> PResult<Break> { pub fn parse_break(&mut self) -> PResult<Break> {
self.match_kw(Keyword::Break, Parsing::Break)?; self.match_kw(Keyword::Break, Parsing::Break)?;
@ -1189,9 +1196,9 @@ impl<'t> Parser<'t> {
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
} }
macro operator($($name:ident ($returns:ident) {$($t:ident => $p:ident),*$(,)?};)*) {$( macro operator($($name:ident ($returns:ident) {$($t:ident => $p:ident),*$(,)?};)*) {$(
pub fn $name (&mut self) -> PResult<$returns> { pub fn $name (&mut self) -> PResult<$returns> {
const PARSING: Parsing = Parsing::$returns; const PARSING: Parsing = Parsing::$returns;
let out = Ok(match self.peek_type(PARSING) { let out = Ok(match self.peek_type(PARSING) {
@ -1204,8 +1211,8 @@ macro operator($($name:ident ($returns:ident) {$($t:ident => $p:ident),*$(,)?};)
} }
)*} )*}
/// ## Operator Kinds /// ## Operator Kinds
impl<'t> Parser<'t> { impl<'t> Parser<'t> {
operator! { operator! {
assign_op (AssignKind) { assign_op (AssignKind) {
Eq => Plain, // = Eq => Plain, // =
@ -1272,4 +1279,5 @@ impl<'t> Parser<'t> {
self.consume_peeked(); self.consume_peeked();
Ok(()) Ok(())
} }
}
} }