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 {
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 println!("end");
113 buf.clear();
114 continue;
115 }
116
117 buf.extend_from_slice(line.as_bytes());
118 buf.push(b'\n');
119 }
120}