lexa_syn/parser.rs
1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ __ _ ____ ______ ┃
3// ┃ ____ / /_ (_)______ __/ __ \/ ____/ ┃
4// ┃ / __ \/ __ \/ / ___/ / / / /_/ / / ┃
5// ┃ / /_/ / / / / (__ ) /_/ / _, _/ /___ ┃
6// ┃ / .___/_/ /_/_/____/\__, /_/ |_|\____/ ┃
7// ┃ /_/ /____/ ┃
8// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
9// ┃ Copyright: (c) 2023, Mike 'PhiSyX' S. (https://github.com/PhiSyX) ┃
10// ┃ GNU General Public License v3.0+: ┃
11// ┃ see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt ┃
12// ┃ SPDX-License-Identifier: GPL-3.0-or-later ┃
13// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
14// ┃ ┃
15// ┃ This file is part of phisyRC. ┃
16// ┃ ┃
17// ┃ phisyRC is free software: you can redistribute it and/or modify it under ┃
18// ┃ the terms of the GNU General Public License as published by the ┃
19// ┃ Free Software Foundation, either version 3 of the License, or (at your ┃
20// ┃ option) any later version. ┃
21// ┃ ┃
22// ┃ phisyRC is distributed in the hope that it will be useful, but WITHOUT ┃
23// ┃ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ┃
24// ┃ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ┃
25// ┃ more details. ┃
26// ┃ ┃
27// ┃ You should have received a copy of the GNU General Public License along ┃
28// ┃ with phisyRC. ┃
29// ┃ ┃
30// ┃ If not, see <https://www.gnu.org/licenses/>. ┃
31// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
32
33use std::error;
34
35use syn;
36use syn::__private::{Span, TokenStream};
37
38// --------- //
39// Interface //
40// --------- //
41
42pub trait Parser {
43 type Input: syn::parse::Parse;
44 type Err<'err>: ParserError<'err>
45 where
46 Self: 'err;
47
48 fn new(_: Self::Input) -> Self;
49
50 fn analyze(&self) -> Result<TokenStream, Self::Err<'_>>;
51}
52
53pub trait ParserError<'err>: error::Error {
54 fn compile_error(self) -> TokenStream;
55
56 fn span(self) -> Span;
57}
58
59// -------- //
60// Fonction //
61// -------- //
62
63pub fn parse<'t, P>(input: TokenStream) -> TokenStream
64where
65 P: 't,
66 P: Parser,
67{
68 let input = syn::parse_macro_input!(input as P::Input);
69 let parser = P::new(input);
70 let output = parser.analyze();
71 match output {
72 | Ok(token_stream) => token_stream,
73 | Err(err) => err.compile_error(),
74 }
75}