Skip to main content

mech_syntax/
grammar.rs

1#[macro_use]
2use crate::*;
3
4#[cfg(not(feature = "no-std"))] use core::fmt;
5#[cfg(feature = "no-std")] use alloc::fmt;
6#[cfg(feature = "no-std")] use alloc::string::String;
7#[cfg(feature = "no-std")] use alloc::vec::Vec;
8use nom::{
9  branch::alt,
10  bytes::complete::tag,
11  character::complete::{anychar, char as nom_char, digit1, satisfy},
12  combinator::{map, map_res, opt},
13  multi::{many0, many1, separated_list1},
14  sequence::{delimited, preceded, tuple as nom_tuple},
15  IResult,
16};
17
18
19use std::collections::HashMap;
20use colored::*;
21
22use crate::*;
23
24// grammar := +rule ;
25pub fn grammar(input: ParseString) -> ParseResult<Grammar> {
26  let ((input, rules)) = many1(rule)(input)?;
27  let (input, _) = new_line(input)?;
28  Ok((input, Grammar { rules }))
29}
30
31// grammar-identifier := alpha_token, *(alpha_token | digit_token | dash) ;
32fn grammar_identifier(input: ParseString) -> ParseResult<GrammarIdentifier> {
33  let (input, first) = alpha_token(input)?;
34  let (input, mut rest) = many0(alt((alpha_token, digit_token, dash)))(input)?;
35  let mut id = vec![first];
36  id.extend(rest);
37  let name = Token::merge_tokens(&mut id).unwrap();
38  Ok((input, GrammarIdentifier{name}))
39}
40
41// rule := grammar-identifier, define_operator, grammar_expression, semicolon ;
42fn rule(input: ParseString) -> ParseResult<Rule> {
43  let ((input, name)) = grammar_identifier(input)?;
44  let ((input, _)) = define_operator(input)?;
45  let ((input, expr)) = grammar_expression(input)?;
46  let ((input, _)) = semicolon(input)?;
47  Ok((input, Rule { name, expr }))
48}
49
50// grammar-expression := term, *( "|" term ) ;
51fn grammar_expression(input: ParseString) -> ParseResult<GrammarExpression> {
52  let (input, first) = term(input)?;
53  let (input, rest) = many0(nom_tuple((bar, term)))(input)?;
54  if rest.len() == 0 {
55    Ok((input,first))
56  } else {
57    let mut choice = vec![first];
58    choice.extend(rest.into_iter().map(|(_, term)| term));
59    Ok((input, GrammarExpression::Choice(choice)))
60  }
61}
62
63// term := factor, *( "," factor ) ;
64fn term(input: ParseString) -> ParseResult<GrammarExpression> {
65  let (input, first) = factor(input)?;
66  let (input, rest) = many0(nom_tuple((comma, factor)))(input)?;
67  let mut seq: Vec<GrammarExpression> = vec![first];
68  seq.extend(rest.into_iter().map(|(_, factor)| factor));
69  if seq.len() == 1 {
70    return Ok((input, seq.pop().unwrap()));
71  }
72  Ok((input, GrammarExpression::Sequence(seq)))
73}
74
75// definition := grammar_identifier ;
76fn definition(input: ParseString) -> ParseResult<GrammarExpression> {
77  let (input, id) = grammar_identifier(input)?;
78  Ok((input, GrammarExpression::Definition(id)))
79}
80
81// repeat0 := "*", factor ;
82fn repeat0(input: ParseString) -> ParseResult<GrammarExpression> {
83  let (input, _) = asterisk(input)?;
84  let (input, expr) = factor(input)?;
85  Ok((input, GrammarExpression::Repeat0(Box::new(expr))))
86}
87
88// repeat1 := "+", factor ;
89fn repeat1(input: ParseString) -> ParseResult<GrammarExpression> {
90  let (input, _) = plus(input)?;
91  let (input, expr) = factor(input)?;
92  Ok((input, GrammarExpression::Repeat1(Box::new(expr))))
93}
94
95// optional := "?", factor ;
96fn optional(input: ParseString) -> ParseResult<GrammarExpression> {
97  let (input, _) = question(input)?;
98  let (input, expr) = factor(input)?;
99  Ok((input, GrammarExpression::Optional(Box::new(expr))))
100}
101
102// peek := ">", factor ;
103fn peek(input: ParseString) -> ParseResult<GrammarExpression> {
104  let (input, _) = right_angle(input)?;
105  let (input, expr) = factor(input)?;
106  Ok((input, GrammarExpression::Peek(Box::new(expr))))
107}
108
109// not := "¬", factor ;
110fn not(input: ParseString) -> ParseResult<GrammarExpression> {
111  let (input, _) = negate(input)?;
112  let (input, expr) = factor(input)?;
113  Ok((input, GrammarExpression::Not(Box::new(expr))))
114}
115
116// list := "[", factor, ",", factor, "]" ;
117fn list(input: ParseString) -> ParseResult<GrammarExpression> {
118  let (input, _) = left_bracket(input)?;
119  let (input, first) = factor(input)?;
120  let (input, _) = comma(input)?;
121  let (input, second) = factor(input)?;
122  let (input, _) = right_bracket(input)?;
123  Ok((input, GrammarExpression::List(Box::new(first), Box::new(second))))
124}
125
126// g-range := terminal, "..", terminal ;
127fn g_range(input: ParseString) -> ParseResult<GrammarExpression> {
128  let (input, start) = terminal_token(input)?;
129  let (input, _) = tuple((period,period))(input)?;
130  let (input, end) = terminal_token(input)?;
131  Ok((input, GrammarExpression::Range(start, end)))
132}
133
134// factor := repeat0 | repeat1 | optional | peek | not | group | definition | terminal ;
135fn factor(input: ParseString) -> ParseResult<GrammarExpression> {
136  alt((
137    repeat0,
138    repeat1,
139    optional,
140    peek,
141    not,
142    group,
143    list,
144    definition,
145    g_range,
146    terminal,
147  ))(input)
148  
149}
150  
151// group := "(", GrammarExpression, ")" ;
152fn group(input: ParseString) -> ParseResult<GrammarExpression> {
153  let (input, expr) = delimited(left_parenthesis, grammar_expression, right_parenthesis)(input)?;
154  Ok((input, GrammarExpression::Group(Box::new(expr))))
155}
156
157// terminal := quote, +any_token, quote ;
158fn terminal(input: ParseString) -> ParseResult<GrammarExpression> {
159  let (input, trminl) = terminal_token(input)?;
160  Ok((input, GrammarExpression::Terminal(trminl)))
161}
162
163// terminal := quote, +any_token, quote ;
164fn terminal_token(input: ParseString) -> ParseResult<Token> {
165  let (input, _) = quote(input)?;
166  let (input, mut t) = many0(tuple((is_not(quote),any_token)))(input)?;
167  let (input, _) = quote(input)?;
168  let mut t = t.into_iter().map(|(_,b)| b).collect::<Vec<Token>>();
169  let token =  Token::merge_tokens(&mut t).unwrap();
170  Ok((input,token))
171}