Skip to content

Commit 28f59b5

Browse files
authored
Merge pull request #549 from ratmice/lrpar_section_parser_ctbuilder_take2
Lrpar section parser ctbuilder take2
2 parents 92535e1 + c5d7b00 commit 28f59b5

23 files changed

Lines changed: 1492 additions & 370 deletions

File tree

cfgrammar/src/lib/header.rs

Lines changed: 240 additions & 40 deletions
Large diffs are not rendered by default.

cfgrammar/src/lib/markmap.rs

Lines changed: 831 additions & 0 deletions
Large diffs are not rendered by default.

cfgrammar/src/lib/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,17 @@ use bincode::{Decode, Encode};
5656
#[cfg(feature = "serde")]
5757
use serde::{Deserialize, Serialize};
5858

59-
#[doc(hidden)]
6059
pub mod header;
6160
mod idxnewtype;
61+
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;
67-
pub use span::{Span, Spanned};
69+
pub use span::{Location, Span, Spanned};
6870

6971
/// A type specifically for rule indices.
7072
pub use crate::idxnewtype::{PIdx, RIdx, SIdx, TIdx};

cfgrammar/src/lib/span.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,12 @@ impl ToTokens for Span {
6666
tokens.append_all(quote! {::cfgrammar::Span::new(#start, #end)});
6767
}
6868
}
69+
70+
/// A possibly inexact location which could either be a `Span`,
71+
/// a command-line option, or some other location described textually.
72+
#[derive(Clone, Debug, Eq, PartialEq)]
73+
pub enum Location {
74+
Span(Span),
75+
CommandLine,
76+
Other(String),
77+
}

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: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,34 @@ use std::{
66
use indexmap::{IndexMap, IndexSet};
77

88
use super::{
9-
parser::YaccParser, Precedence, YaccGrammarError, YaccGrammarErrorKind, YaccGrammarWarning,
10-
YaccGrammarWarningKind, YaccKind, YaccKindResolver,
9+
parser::YaccParser, ParserError, Precedence, YaccGrammarError, YaccGrammarErrorKind,
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 {
1717
yacc_kind: Option<YaccKind>,
1818
ast: GrammarAST,
19-
errs: Vec<YaccGrammarError>,
19+
errs: Vec<ParserError>,
2020
}
2121

2222
impl ASTWithValidityInfo {
2323
/// Parses a source file into an AST, returning an ast and any errors that were
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() {
34-
ast.complete_and_validate().map_err(|e| errs.push(e)).ok();
34+
ast.complete_and_validate()
35+
.map_err(|e| errs.push(e.into()))
36+
.ok();
3537
}
3638
(yacc_kind, ast)
3739
};
@@ -62,7 +64,7 @@ impl ASTWithValidityInfo {
6264
}
6365

6466
/// Returns all errors which were encountered during AST construction.
65-
pub fn errors(&self) -> &[YaccGrammarError] {
67+
pub fn errors(&self) -> &[ParserError] {
6668
self.errs.as_slice()
6769
}
6870
}

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)