parse/
parse.rs

1use general_parser::{
2	BinaryOperator, Configuration, Expression, ExpressionRepresentation, UnaryOperator,
3};
4
5fn main() {
6	let arg = std::env::args().nth(1);
7
8	if let Some("--interactive") = arg.as_deref() {
9		run_interactive();
10		return;
11	}
12
13	let configuration = Configuration {
14		binary_operators: vec![
15			BinaryOperator { representation: "*", precedence: 4 },
16			BinaryOperator { representation: "+", precedence: 3 },
17		],
18		..Default::default()
19	};
20
21	if let Some(source) = std::env::args().nth(1) {
22		let allocator = bumpalo::Bump::new();
23		let expression: Expression<&str> =
24			Expression::from_string(&source, &configuration, &allocator);
25		eprintln!("{expression:#?}");
26	} else {
27		let sources: &[&str] = &["(x (a * b) (d * 2 + e))", "(x (a b) (c d e))"];
28
29		for source in sources {
30			let allocator = bumpalo::Bump::new();
31			let expression: Expression<&str> =
32				Expression::from_string(source, &configuration, &allocator);
33			let expression = ExpressionRepresentation(&expression);
34			eprintln!("{expression}");
35		}
36	}
37}
38
39fn run_interactive() {
40	use std::io::{BufRead, stdin};
41	let stdin = stdin();
42	let mut buf = Vec::new();
43
44	println!("start");
45
46	for line in stdin.lock().lines().map_while(Result::ok) {
47		if line == "close" {
48			if !buf.is_empty() {
49				eprintln!("no end to message {buf:?}");
50			}
51			break;
52		}
53
54		if line == "end" {
55			let output = String::from_utf8_lossy(&buf);
56
57			let (configuration, source) = if let Some((config, source)) = output.split_once("\n---")
58			{
59				let mut configuration = Configuration::default();
60				for line in config.lines() {
61					let (adjacent, operation) = if let Some(rest) = line.strip_suffix(" (adjacent)")
62					{
63						(true, rest)
64					} else {
65						(false, line)
66					};
67					let (syntax, precedence) = operation.split_once(' ').unwrap();
68					let precedence: u8 = precedence.parse().expect("invalid precedence");
69					if let Some(syntax) = syntax.strip_prefix('_') {
70						if let Some(representation) = syntax.strip_suffix('_') {
71							let operator = BinaryOperator { representation, precedence };
72							if adjacent {
73								configuration.adjacency = Some(general_parser::Adjacency {
74									operator,
75									functions: Vec::new(),
76								});
77							} else {
78								configuration.binary_operators.push(operator);
79							}
80						} else {
81							let representation = syntax;
82							configuration
83								.postfix_unary_operators
84								.push(UnaryOperator { representation, precedence });
85						}
86					} else {
87						let representation = syntax.strip_suffix('_').unwrap();
88						configuration
89							.prefix_unary_operators
90							.push(UnaryOperator { representation, precedence });
91					}
92				}
93				(configuration, source)
94			} else {
95				(Configuration::default(), &*output)
96			};
97
98			// eprintln!("{configuration:?} {source}");
99
100			{
101				let allocator = bumpalo::Bump::new();
102				let expression: Expression<&str> =
103					Expression::from_string(&source, &configuration, &allocator);
104				let expression = ExpressionRepresentation(&expression);
105				println!("{expression}");
106			}
107
108			// if let Err(error) = out {
109			//     println!("Error: {error:?}");
110			// }
111
112			println!("end");
113			buf.clear();
114			continue;
115		}
116
117		buf.extend_from_slice(line.as_bytes());
118		buf.push(b'\n');
119	}
120}