Skip to content

Commit 60c486d

Browse files
committed
Implement parse_generictree and parse_noaction using parse_map, and deprecate them
1 parent 5455a74 commit 60c486d

File tree

5 files changed

+31
-154
lines changed

5 files changed

+31
-154
lines changed

lrlex/src/lib/ctbuilder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ where
548548
let input = fs::read_to_string(&path)?;
549549
let l: LRNonStreamingLexer<LexerTypesT> =
550550
closure_lexerdef.lexer(&input);
551+
#[allow(deprecated)]
551552
for e in rtpb.parse_noaction(&l) {
552553
Err(format!("parsing {}: {}", path.display(), e))?
553554
}

lrpar/src/lib/ctbuilder.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ where
977977
#[allow(unused_imports)]
978978
pub use _parser_::*;
979979
#[allow(unused_imports)]
980-
use ::lrpar::Lexeme;
980+
use ::lrpar::{Lexeme, Node};
981981
} // End of `mod #mod_name`
982982
};
983983
// Try and run a code formatter on the generated code.
@@ -1069,14 +1069,18 @@ where
10691069
quote! {
10701070
::lrpar::RTParserBuilder::new(&grm, &stable)
10711071
.recoverer(#recoverer)
1072-
.parse_generictree(lexer)
1072+
.parse_map(
1073+
lexer,
1074+
&|lexeme| Node::Term{lexeme},
1075+
&|ridx, nodes| Node::Nonterm{ridx, nodes}
1076+
)
10731077
}
10741078
}
10751079
YaccKind::Original(YaccOriginalActionKind::NoAction) => {
10761080
quote! {
10771081
::lrpar::RTParserBuilder::new(&grm, &stable)
10781082
.recoverer(#recoverer)
1079-
.parse_noaction(lexer)
1083+
.parse_map(lexer, &|_| (), &|_, _| ()).1
10801084
}
10811085
}
10821086
YaccKind::Original(YaccOriginalActionKind::UserAction) | YaccKind::Grmtools => {

lrpar/src/lib/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ pub use crate::{
211211
parser::{LexParseError, Node, ParseError, ParseRepair, RTParserBuilder, RecoveryKind},
212212
};
213213

214+
#[allow(deprecated)]
214215
pub use crate::parser::action_generictree;
215216
/// A convenience macro for including statically compiled `.y` files. A file `src/a/b/c.y`
216217
/// processed by [CTParserBuilder::grammar_in_src_dir] can then be used in a crate with

lrpar/src/lib/parser.rs

Lines changed: 14 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -206,61 +206,10 @@ where
206206
fnonterm(ridx, nodes)
207207
}
208208

209-
impl<
210-
'a,
211-
'b: 'a,
212-
'input: 'b,
213-
StorageT: 'static + Debug + Hash + PrimInt + Unsigned,
214-
LexerTypesT: LexerTypes<StorageT = StorageT>,
215-
> Parser<'a, 'b, 'input, StorageT, LexerTypesT, Node<LexerTypesT::LexemeT, StorageT>, ()>
216-
where
217-
usize: AsPrimitive<StorageT>,
218-
{
219-
fn parse_generictree(
220-
rcvry_kind: RecoveryKind,
221-
grm: &YaccGrammar<StorageT>,
222-
token_cost: TokenCostFn<'a, StorageT>,
223-
stable: &StateTable<StorageT>,
224-
lexer: &'b dyn NonStreamingLexer<'input, LexerTypesT>,
225-
lexemes: Vec<LexerTypesT::LexemeT>,
226-
) -> (
227-
Option<Node<LexerTypesT::LexemeT, StorageT>>,
228-
Vec<LexParseError<StorageT, LexerTypesT>>,
229-
) {
230-
for tidx in grm.iter_tidxs() {
231-
assert!(token_cost(tidx) > 0);
232-
}
233-
let mut actions: Vec<
234-
ActionFn<
235-
'a,
236-
'b,
237-
'input,
238-
StorageT,
239-
LexerTypesT,
240-
Node<LexerTypesT::LexemeT, StorageT>,
241-
(),
242-
>,
243-
> = Vec::new();
244-
actions.resize(usize::from(grm.prods_len()), &action_generictree);
245-
let psr = Parser {
246-
rcvry_kind,
247-
grm,
248-
token_cost: Box::new(token_cost),
249-
stable,
250-
lexer,
251-
lexemes,
252-
actions: actions.as_slice(),
253-
param: (),
254-
};
255-
let mut pstack = vec![stable.start_state()];
256-
let mut astack = Vec::new();
257-
let mut errors = Vec::new();
258-
let mut spans = Vec::new();
259-
let accpt = psr.lr(0, &mut pstack, &mut astack, &mut errors, &mut spans);
260-
(accpt, errors)
261-
}
262-
}
263-
209+
#[deprecated(
210+
since = "0.14",
211+
note = "Deprecated with `parse_generictree` there is no direct replacement, besides a custom action"
212+
)]
264213
/// The action which implements [`cfgrammar::yacc::YaccOriginalActionKind::GenericParseTree`].
265214
/// Usually you should just use the action kind directly. But you can also call this from
266215
/// within a custom action to return a generic parse tree with custom behavior.
@@ -285,57 +234,6 @@ where
285234
Node::Nonterm { ridx, nodes }
286235
}
287236

288-
impl<
289-
'a,
290-
'b: 'a,
291-
'input: 'b,
292-
StorageT: 'static + Debug + Hash + PrimInt + Unsigned,
293-
LexerTypesT: LexerTypes<StorageT = StorageT>,
294-
> Parser<'a, 'b, 'input, StorageT, LexerTypesT, (), ()>
295-
where
296-
usize: AsPrimitive<StorageT>,
297-
{
298-
fn parse_noaction(
299-
rcvry_kind: RecoveryKind,
300-
grm: &YaccGrammar<StorageT>,
301-
token_cost: TokenCostFn<'a, StorageT>,
302-
stable: &StateTable<StorageT>,
303-
lexer: &'b dyn NonStreamingLexer<'input, LexerTypesT>,
304-
lexemes: Vec<LexerTypesT::LexemeT>,
305-
) -> Vec<LexParseError<StorageT, LexerTypesT>> {
306-
for tidx in grm.iter_tidxs() {
307-
assert!(token_cost(tidx) > 0);
308-
}
309-
let mut actions: Vec<ActionFn<'a, 'b, 'input, StorageT, LexerTypesT, (), ()>> = Vec::new();
310-
actions.resize(usize::from(grm.prods_len()), &Parser::noaction);
311-
let psr = Parser {
312-
rcvry_kind,
313-
grm,
314-
token_cost: Box::new(token_cost),
315-
stable,
316-
lexer,
317-
lexemes,
318-
actions: actions.as_slice(),
319-
param: (),
320-
};
321-
let mut pstack = vec![stable.start_state()];
322-
let mut astack = Vec::new();
323-
let mut errors = Vec::new();
324-
let mut spans = Vec::new();
325-
psr.lr(0, &mut pstack, &mut astack, &mut errors, &mut spans);
326-
errors
327-
}
328-
329-
fn noaction(
330-
_ridx: RIdx<StorageT>,
331-
_lexer: &dyn NonStreamingLexer<LexerTypesT>,
332-
_span: Span,
333-
_astack: vec::Drain<AStackType<LexerTypesT::LexemeT, ()>>,
334-
_param: (),
335-
) {
336-
}
337-
}
338-
339237
impl<
340238
'a,
341239
'b: 'a,
@@ -1025,6 +923,10 @@ where
1025923
self
1026924
}
1027925

926+
#[deprecated(
927+
since = "0.14",
928+
note = "Use `parse_map` to return a `lrpar::Node` instead"
929+
)]
1028930
/// Parse input, and (if possible) return a generic parse tree. See the arguments for
1029931
/// [`parse_actions`](#method.parse_actions) for more details about the return value.
1030932
pub fn parse_generictree(
@@ -1034,21 +936,9 @@ where
1034936
Option<Node<LexerTypesT::LexemeT, StorageT>>,
1035937
Vec<LexParseError<StorageT, LexerTypesT>>,
1036938
) {
1037-
let mut lexemes = vec![];
1038-
for e in lexer.iter().collect::<Vec<_>>() {
1039-
match e {
1040-
Ok(l) => lexemes.push(l),
1041-
Err(e) => return (None, vec![e.into()]),
1042-
}
1043-
}
1044-
Parser::<StorageT, LexerTypesT, Node<LexerTypesT::LexemeT, StorageT>, ()>::parse_generictree(
1045-
self.recoverer,
1046-
self.grm,
1047-
self.term_costs,
1048-
self.stable,
1049-
lexer,
1050-
lexemes,
1051-
)
939+
self.parse_map(lexer, &|lexeme| Node::Term { lexeme }, &|ridx, nodes| {
940+
Node::Nonterm { ridx, nodes }
941+
})
1052942
}
1053943

1054944
/// Parse input, and (if possible) return a generic parse tree. See the arguments for
@@ -1086,27 +976,14 @@ where
1086976
)
1087977
}
1088978

979+
#[deprecated(since = "0.14", note = "Use `parse_map` instead")]
1089980
/// Parse input, returning any errors found. See the arguments for
1090981
/// [`parse_actions`](#method.parse_actions) for more details about the return value.
1091982
pub fn parse_noaction(
1092983
&self,
1093984
lexer: &dyn NonStreamingLexer<LexerTypesT>,
1094985
) -> Vec<LexParseError<StorageT, LexerTypesT>> {
1095-
let mut lexemes = vec![];
1096-
for e in lexer.iter().collect::<Vec<_>>() {
1097-
match e {
1098-
Ok(l) => lexemes.push(l),
1099-
Err(e) => return vec![e.into()],
1100-
}
1101-
}
1102-
Parser::<StorageT, LexerTypesT, (), ()>::parse_noaction(
1103-
self.recoverer,
1104-
self.grm,
1105-
self.term_costs,
1106-
self.stable,
1107-
lexer,
1108-
lexemes,
1109-
)
986+
self.parse_map(lexer, &|_| (), &|_, _| ()).1
1110987
}
1111988

1112989
/// Parse input, execute actions, and return the associated value (if possible) and/or any
@@ -1259,6 +1136,7 @@ pub(crate) mod test {
12591136
.iter()
12601137
.map(|(k, v)| (grm.token_idx(k).unwrap(), v))
12611138
.collect::<HashMap<_, _>>();
1139+
#[allow(deprecated)]
12621140
let (r, errs) = RTParserBuilder::new(&grm, &stable)
12631141
.recoverer(rcvry_kind)
12641142
.term_costs(&|tidx| **costs_tidx.get(&tidx).unwrap_or(&&1))
@@ -1561,18 +1439,6 @@ Factor : 'INT';";
15611439
",
15621440
);
15631441

1564-
assert_eq!(
1565-
rt_parser.parse_generictree(&lexer).0.unwrap(),
1566-
rt_parser
1567-
.parse_map(
1568-
&lexer,
1569-
&|lexeme: TestLexeme| { Node::Term { lexeme } },
1570-
&|ridx, nodes| { Node::Nonterm { ridx, nodes } },
1571-
)
1572-
.0
1573-
.unwrap()
1574-
);
1575-
15761442
let expected_parse_map = {
15771443
use TestParseMap::*;
15781444
NonTerm(

nimbleparse/src/main.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use cfgrammar::{
77
use getopts::Options;
88
use lrlex::{DefaultLexerTypes, LRLexError, LRNonStreamingLexerDef, LexerDef};
99
use lrpar::{
10-
LexerTypes,
10+
LexerTypes, Node,
1111
diagnostics::{DiagnosticFormatter, SpannedDiagnosticFormatter},
1212
parser::{RTParserBuilder, RecoveryKind},
1313
};
@@ -479,7 +479,9 @@ where
479479
fn parse_string(self, input_path: PathBuf, input_src: String) -> Result<(), NimbleparseError> {
480480
let lexer = self.lexerdef.lexer(&input_src);
481481
let pb = RTParserBuilder::new(&self.grm, &self.stable).recoverer(self.recoverykind);
482-
let (pt, errs) = pb.parse_generictree(&lexer);
482+
let (pt, errs) = pb.parse_map(&lexer, &|lexeme| Node::Term { lexeme }, &|ridx, nodes| {
483+
Node::Nonterm { ridx, nodes }
484+
});
483485
match pt {
484486
Some(pt) => println!("{}", pt.pp(&self.grm, &input_src)),
485487
None => println!("Unable to repair input sufficiently to produce parse tree.\n"),
@@ -559,7 +561,10 @@ where
559561
for input_path in input_paths {
560562
let input = read_file(&input_path);
561563
let lexer = self.lexerdef.lexer(&input);
562-
let (pt, errs) = pb.parse_generictree(&lexer);
564+
let (pt, errs) =
565+
pb.parse_map(&lexer, &|lexeme| Node::Term { lexeme }, &|ridx, nodes| {
566+
Node::Nonterm { ridx, nodes }
567+
});
563568
if errs.is_empty() && pt.is_some() {
564569
// Since we're parsing many files, don't output all of their parse trees, just print the file name.
565570
println!("parsed: {}", input_path.display())

0 commit comments

Comments
 (0)