1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use crate::{ast, lexer::Lexer, parser};
pub use crate::lexer::{LexerPosition, LexicalError, Token};
mod parsable;
pub use parsable::Parsable;
mod context;
pub use context::*;
pub type ParseError = lang_util::error::ParseError<LexicalError>;
pub trait LangParser: Sized {
fn new() -> Self;
}
pub trait Parse: Sized {
type Parser: LangParser;
fn parse(source: &str) -> Result<Self, ParseError> {
<Self as Parse>::parse_with_options(source, &Default::default())
.map(|(parsed, _names)| parsed)
}
fn parse_with_options(
source: &str,
opts: &ParseContext,
) -> Result<(Self, ParseContext), ParseError>;
fn parse_with_parser<'i>(
source: &'i str,
opts: &ParseContext,
parser: &Self::Parser,
) -> Result<(Self, ParseContext), ParseError>;
}
macro_rules! impl_parse {
($t:ty => $p:ty) => {
impl LangParser for $p {
fn new() -> Self {
<$p>::new()
}
}
impl Parse for $t {
type Parser = $p;
fn parse_with_options<'i>(
source: &'i str,
opts: &ParseContext,
) -> Result<(Self, ParseContext), ParseError> {
let parser = <$p>::new();
Self::parse_with_parser(source, opts, &parser)
}
fn parse_with_parser<'i>(
source: &'i str,
opts: &ParseContext,
parser: &$p,
) -> Result<(Self, ParseContext), ParseError> {
let cloned_opts = opts.clone_inner();
let lexer = Lexer::new(source, cloned_opts.clone());
parser
.parse(source, lexer)
.map(|parsed| (parsed, cloned_opts))
.map_err(|err| ParseError::new(err, source))
}
}
};
}
#[cfg(feature = "parser-expr")]
impl_parse!(ast::Expr => parser::ExprParser);
#[cfg(feature = "parser-preprocessor")]
impl_parse!(ast::Preprocessor => parser::PreprocessorParser);
#[cfg(feature = "parser-statement")]
impl_parse!(ast::Statement => parser::StatementParser);
impl_parse!(ast::TranslationUnit => parser::TranslationUnitParser);