syntax_parser_generator/
lib.rs

1//! Independent library for generating lexical-analyzers and LALR parsers.
2//!
3//! This library offers a simple API for generating parsers of syntactically-structured text. As
4//! such, it can generate 2 types of engines - for the 2 phases of syntax parsing, which naturally
5//! fit on top of each other:
6//!
7//! * [_Lexical analyzers_](https://en.wikipedia.org/wiki/Lexical_analysis): for tokenizing input
8//!     text by regular expressions.
9//! * [_Syntax-directed translators_](https://en.wikipedia.org/wiki/Syntax-directed_translation):
10//!     for reconstructing the input's syntax-tree by a context-free grammar (using the
11//!     [LALR](https://en.wikipedia.org/wiki/LALR_parser) algorithm), and translating it into some
12//!     user-defined representation, such as an abstract syntax-tree (AST) or a sequence of
13//!     intermediate code representation (IR).
14//!
15//! Check out the [lex] and [parsing] modules, respectively, for these purposes.
16//!
17//! Note that the crate is independent: its entire API and logic is designed and implemented
18//! in-house.
19//!
20//! # Example
21//!
22//! ```rust
23//! # use syntax_parser_generator::handles::specials::AutomaticallyHandled;
24//! # use syntax_parser_generator::lex::{LexemeDescriptor, LexicalAnalyzer, Regex};
25//! # use syntax_parser_generator::parsing::{Associativity, SyntaxDirectedTranslator, SyntaxDirectedTranslatorBuilder};
26//! # use syntax_parser_generator::readers::ByteArrayReader;
27//! # #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28//! enum LexemeType { Plus, Star, Integer }
29//! # impl AutomaticallyHandled for LexemeType {
30//! #    type HandleCoreType = u8;
31//! #    fn serial(&self) -> usize { *self as usize }
32//! # }
33//!
34//! fn build_lexer() -> LexicalAnalyzer<LexemeType> {
35//!     LexicalAnalyzer::new(vec![
36//!         LexemeDescriptor::special_char(LexemeType::Plus, '+'),
37//!         LexemeDescriptor::special_char(LexemeType::Star, '*'),
38//!         LexemeDescriptor::new(
39//!             LexemeType::Integer,
40//!             Regex::plus_from(Regex::character_range('0', '9')),
41//!         ),
42//!     ])
43//! }
44//!
45//! struct ParsingContext {
46//!     integer_count: usize,
47//!     op_count: usize,
48//! }
49//! impl ParsingContext {
50//!     fn new() -> Self {
51//!         Self {
52//!             integer_count: 0,
53//!             op_count: 0,
54//!         }
55//!     }
56//!     fn integer(&mut self, lexeme: String) -> Option<i32> {
57//!         self.integer_count += 1;
58//!         Some(lexeme.parse().ok()?)
59//!     }
60//!     fn sum(&mut self, satellites: Vec<Option<i32>>) -> Option<i32> {
61//!         self.op_count += 1;
62//!         Some(satellites[0]? + satellites[2]?)
63//!     }
64//!     fn mult(&mut self, satellites: Vec<Option<i32>>) -> Option<i32> {
65//!         self.op_count += 1;
66//!         Some(satellites[0]? * satellites[2]?)
67//!     }
68//! }
69//!
70//! fn build_parser() -> SyntaxDirectedTranslator<LexemeType, ParsingContext, Option<i32>> {
71//!     let mut builder = SyntaxDirectedTranslatorBuilder::new();
72//!
73//!     builder.dub_lexeme_types(vec![
74//!         (LexemeType::Integer, "INTEGER"),
75//!         (LexemeType::Plus, "+"),
76//!         (LexemeType::Star, "*"),
77//!     ].into_iter());
78//!     builder.new_nonterminal("expression");
79//!     builder.set_start_nonterminal("expression");
80//!
81//!     builder.new_binding(
82//!         vec!["*"],
83//!         Associativity::Left,
84//!         "multiplicative",
85//!     );
86//!     builder.new_binding(
87//!         vec!["+"],
88//!         Associativity::Left,
89//!         "additive",
90//!     );
91//!
92//!     builder.set_leaf_satellite_builder("INTEGER", ParsingContext::integer);
93//!     builder.set_default_leaf_satellite_builder(|_, _| None);
94//!
95//!     builder.register_identity_rule("expression", "INTEGER");
96//!     builder.register_bound_rule(
97//!         "expression",
98//!         vec!["expression", "+", "expression"],
99//!         "additive",
100//!         ParsingContext::sum,
101//!     );
102//!     builder.register_bound_rule(
103//!         "expression",
104//!         vec!["expression", "*", "expression"],
105//!         "multiplicative",
106//!         ParsingContext::mult,
107//!     );
108//!     builder.build()
109//! }
110//!
111//! fn main() {
112//!     let lexer = build_lexer();
113//!     let parser = build_parser();
114//!     let mut context = ParsingContext::new();
115//!
116//!     let mut input = ByteArrayReader::from_string_slice("12+4*5+8");
117//!     assert_eq!(parser.translate(&mut context, lexer.analyze(&mut input)), Some(Some(40)));
118//!     assert_eq!(context.integer_count, 4);
119//!     assert_eq!(context.op_count, 3);
120//! }
121//! ```
122
123#![warn(missing_docs)]
124
125mod automata;
126pub mod handles;
127pub mod lex;
128pub mod parsing;
129pub mod readers;