Skip to content

Commit c5d7b00

Browse files
committed
Use Header in parsers, instead of YaccKindResolver.
1 parent b0bbc9e commit c5d7b00

21 files changed

Lines changed: 288 additions & 273 deletions

File tree

cfgrammar/src/lib/header.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use crate::{
2-
markmap::MarkMap,
2+
markmap::{Entry, MarkMap},
33
yacc::{ParserError, YaccKind, YaccOriginalActionKind},
44
Location, Span,
55
};
66
use lazy_static::lazy_static;
77
use regex::{Regex, RegexBuilder};
8-
use std::collections::{hash_map::Entry, HashMap};
98
use std::{error::Error, fmt};
109

1110
/// An error regarding the `%grmtools` header section.
@@ -259,12 +258,10 @@ impl<'input> GrmtoolsSectionParser<'input> {
259258
}
260259

261260
#[allow(clippy::type_complexity)]
262-
pub fn parse(
263-
&'_ self,
264-
) -> Result<(HashMap<String, (Location, Value)>, usize), Vec<HeaderError>> {
261+
pub fn parse(&'_ self) -> Result<(Header, usize), Vec<HeaderError>> {
265262
let mut errs = Vec::new();
266263
if let Some(mut i) = self.lookahead_is(MAGIC, self.parse_ws(0)) {
267-
let mut ret = HashMap::new();
264+
let mut ret = Header::new();
268265
i = self.parse_ws(i);
269266
let section_start_pos = i;
270267
if let Some(j) = self.lookahead_is("{", i) {
@@ -329,7 +326,7 @@ impl<'input> GrmtoolsSectionParser<'input> {
329326
});
330327
Err(errs)
331328
} else {
332-
Ok((HashMap::new(), 0))
329+
Ok((Header::new(), 0))
333330
}
334331
}
335332

cfgrammar/src/lib/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ mod idxnewtype;
6161
pub mod markmap;
6262
pub mod newlinecache;
6363
pub mod span;
64+
#[cfg(test)]
65+
pub mod test_utils;
6466
pub mod yacc;
6567

6668
pub use newlinecache::NewlineCache;

cfgrammar/src/lib/test_utils.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#[allow(unused)]
2+
pub use crate::header::{Header, Value};
3+
pub use crate::markmap::{Entry, MergeBehavior};
4+
pub use crate::Location;
5+
#[macro_export]
6+
#[cfg(test)]
7+
macro_rules! header_for_yacckind {
8+
($yk:expr) => {{
9+
let mut header = Header::new();
10+
match header.entry("yacckind".to_string()) {
11+
Entry::Occupied(_) => unreachable!("Header should be empty"),
12+
Entry::Vacant(v) => {
13+
let mut o = v.insert_entry((
14+
Location::Other("Testsuite".to_string()),
15+
Value::try_from($yk).unwrap(),
16+
));
17+
o.mark_required();
18+
o.set_merge_behavior(MergeBehavior::Ours);
19+
}
20+
};
21+
header
22+
}};
23+
}
24+
25+
pub use header_for_yacckind;

cfgrammar/src/lib/yacc/ast.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use indexmap::{IndexMap, IndexSet};
77

88
use super::{
99
parser::YaccParser, ParserError, Precedence, YaccGrammarError, YaccGrammarErrorKind,
10-
YaccGrammarWarning, YaccGrammarWarningKind, YaccKind, YaccKindResolver,
10+
YaccGrammarWarning, YaccGrammarWarningKind, YaccKind,
1111
};
1212

13-
use crate::Span;
13+
use crate::{header::Header, Span};
1414
/// Contains a `GrammarAST` structure produced from a grammar source file.
1515
/// As well as any errors which occurred during the construction of the AST.
1616
pub struct ASTWithValidityInfo {
@@ -24,10 +24,10 @@ impl ASTWithValidityInfo {
2424
/// encountered during the construction of it. The `ASTWithValidityInfo` can be
2525
/// then unused to construct a `YaccGrammar`, which will either produce an
2626
/// `Ok(YaccGrammar)` or an `Err` which includes these errors.
27-
pub fn new(yacc_kind_resolver: YaccKindResolver, s: &str) -> Self {
27+
pub fn new(header: &mut Header, s: &str) -> Self {
2828
let mut errs = Vec::new();
2929
let (yacc_kind, ast) = {
30-
let mut yp = YaccParser::new(yacc_kind_resolver, s.to_string());
30+
let mut yp = YaccParser::new(header, s.to_string());
3131
yp.parse().map_err(|e| errs.extend(e)).ok();
3232
let (yacc_kind, mut ast) = yp.build();
3333
if yacc_kind.is_some() {

cfgrammar/src/lib/yacc/firsts.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::{RIdx, Symbol, TIdx};
99
/// `Firsts` stores all the first sets for a given grammar. For example, given this code and
1010
/// grammar:
1111
/// ```text
12-
/// let grm = YaccGrammar::new(YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)), "
12+
/// let grm = YaccGrammar::new(&mut Header::new(), "
13+
/// %grmtools{yacckind: YaccKind::Original(YaccOriginalActionKind::GenericParseTree)}
1314
/// S: A 'b';
1415
/// A: 'a'
1516
/// | ;").unwrap();
@@ -143,9 +144,10 @@ where
143144
#[cfg(test)]
144145
mod test {
145146
use super::{
146-
super::{YaccGrammar, YaccKind, YaccKindResolver, YaccOriginalActionKind},
147+
super::{YaccGrammar, YaccKind, YaccOriginalActionKind},
147148
YaccFirsts,
148149
};
150+
use crate::test_utils::*;
149151
use num_traits::{AsPrimitive, PrimInt, Unsigned};
150152

151153
fn has<StorageT: 'static + PrimInt + Unsigned>(
@@ -180,7 +182,7 @@ mod test {
180182
#[test]
181183
fn test_first() {
182184
let grm = YaccGrammar::new(
183-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
185+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
184186
"
185187
%start C
186188
%token c d
@@ -202,7 +204,7 @@ mod test {
202204
#[test]
203205
fn test_first_no_subsequent_rules() {
204206
let grm = YaccGrammar::new(
205-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
207+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
206208
"
207209
%start C
208210
%token c d
@@ -220,7 +222,7 @@ mod test {
220222
#[test]
221223
fn test_first_epsilon() {
222224
let grm = YaccGrammar::new(
223-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
225+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
224226
"
225227
%start A
226228
%token a b c
@@ -241,7 +243,7 @@ mod test {
241243
#[test]
242244
fn test_last_epsilon() {
243245
let grm = YaccGrammar::new(
244-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
246+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
245247
"
246248
%start A
247249
%token b c
@@ -261,7 +263,7 @@ mod test {
261263
#[test]
262264
fn test_first_no_multiples() {
263265
let grm = YaccGrammar::new(
264-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
266+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
265267
"
266268
%start A
267269
%token b c
@@ -277,7 +279,7 @@ mod test {
277279

278280
fn eco_grammar() -> YaccGrammar {
279281
YaccGrammar::new(
280-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
282+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
281283
"
282284
%start S
283285
%token a b c d f
@@ -308,7 +310,7 @@ mod test {
308310
#[test]
309311
fn test_first_from_eco_bug() {
310312
let grm = YaccGrammar::new(
311-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
313+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
312314
"
313315
%start E
314316
%token a b c d e f

cfgrammar/src/lib/yacc/follows.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::{RIdx, Symbol, TIdx};
99
/// `Follows` stores all the Follow sets for a given grammar. For example, given this code and
1010
/// grammar:
1111
/// ```text
12-
/// let grm = YaccGrammar::new(YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)), "
12+
/// let grm = YaccGrammar::new(&mut Header::new(), "
13+
/// %grmtools{yacckind: YaccKind::Original(YaccOriginalActionKind::GenericParseTree)}
1314
/// S: A 'b';
1415
/// A: 'a' | ;
1516
/// ").unwrap();
@@ -115,9 +116,10 @@ where
115116
#[cfg(test)]
116117
mod test {
117118
use super::{
118-
super::{YaccGrammar, YaccKind, YaccKindResolver, YaccOriginalActionKind},
119+
super::{YaccGrammar, YaccKind, YaccOriginalActionKind},
119120
YaccFollows,
120121
};
122+
use crate::test_utils::*;
121123
use num_traits::{AsPrimitive, PrimInt, Unsigned};
122124

123125
fn has<StorageT: 'static + PrimInt + Unsigned>(
@@ -149,7 +151,7 @@ mod test {
149151
fn test_follow() {
150152
// Adapted from p2 of https://www.cs.uaf.edu/~cs331/notes/FirstFollow.pdf
151153
let grm = YaccGrammar::new(
152-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
154+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
153155
"
154156
%start E
155157
%%
@@ -173,7 +175,7 @@ mod test {
173175
fn test_follow2() {
174176
// Adapted from https://www.l2f.inesc-id.pt/~david/w/pt/Top-Down_Parsing/Exercise_5:_Test_2010/07/01
175177
let grm = YaccGrammar::new(
176-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
178+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
177179
"
178180
%start A
179181
%%
@@ -196,7 +198,7 @@ mod test {
196198
#[test]
197199
fn test_follow3() {
198200
let grm = YaccGrammar::new(
199-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
201+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
200202
"
201203
%start S
202204
%%
@@ -213,7 +215,7 @@ mod test {
213215
#[test]
214216
fn test_follow_corchuelo() {
215217
let grm = YaccGrammar::new(
216-
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
218+
&mut header_for_yacckind!(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
217219
"
218220
%start E
219221
%%

0 commit comments

Comments
 (0)