Skip to content

Commit 94622a2

Browse files
committed
Try to give all Productions a span across it's symbols.
1 parent 508cb9b commit 94622a2

File tree

3 files changed

+57
-50
lines changed

3 files changed

+57
-50
lines changed

cfgrammar/src/lib/yacc/ast.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub struct Production {
107107
pub symbols: Vec<Symbol>,
108108
pub precedence: Option<String>,
109109
pub action: Option<String>,
110-
pub empty_span: Option<Span>,
110+
pub prod_span: Span,
111111
}
112112

113113
#[derive(Clone, Debug)]
@@ -186,14 +186,14 @@ impl GrammarAST {
186186
symbols: Vec<Symbol>,
187187
precedence: Option<String>,
188188
action: Option<String>,
189-
empty_span: Option<Span>,
189+
prod_span: Span,
190190
) {
191191
self.rules[&rule_name].pidxs.push(self.prods.len());
192192
self.prods.push(Production {
193193
symbols,
194194
precedence,
195195
action,
196-
empty_span,
196+
prod_span,
197197
});
198198
}
199199

@@ -439,7 +439,7 @@ mod test {
439439
let empty_span = Span::new(0, 0);
440440
grm.start = Some(("A".to_string(), empty_span));
441441
grm.add_rule(("B".to_string(), empty_span), None);
442-
grm.add_prod("B".to_string(), vec![], None, None, None);
442+
grm.add_prod("B".to_string(), vec![], None, None, empty_span);
443443
match grm.complete_and_validate() {
444444
Err(YaccGrammarError {
445445
kind: YaccGrammarErrorKind::InvalidStartRule(_),
@@ -455,7 +455,7 @@ mod test {
455455
let empty_span = Span::new(0, 0);
456456
grm.start = Some(("A".to_string(), empty_span));
457457
grm.add_rule(("A".to_string(), empty_span), None);
458-
grm.add_prod("A".to_string(), vec![], None, None, None);
458+
grm.add_prod("A".to_string(), vec![], None, None, empty_span);
459459
assert!(grm.complete_and_validate().is_ok());
460460
}
461461

@@ -466,8 +466,8 @@ mod test {
466466
grm.start = Some(("A".to_string(), empty_span));
467467
grm.add_rule(("A".to_string(), empty_span), None);
468468
grm.add_rule(("B".to_string(), empty_span), None);
469-
grm.add_prod("A".to_string(), vec![rule("B")], None, None, None);
470-
grm.add_prod("B".to_string(), vec![], None, None, None);
469+
grm.add_prod("A".to_string(), vec![rule("B")], None, None, empty_span);
470+
grm.add_prod("B".to_string(), vec![], None, None, empty_span);
471471
assert!(grm.complete_and_validate().is_ok());
472472
}
473473

@@ -477,7 +477,7 @@ mod test {
477477
let empty_span = Span::new(0, 0);
478478
grm.start = Some(("A".to_string(), empty_span));
479479
grm.add_rule(("A".to_string(), empty_span), None);
480-
grm.add_prod("A".to_string(), vec![rule("B")], None, None, None);
480+
grm.add_prod("A".to_string(), vec![rule("B")], None, None, empty_span);
481481
match grm.complete_and_validate() {
482482
Err(YaccGrammarError {
483483
kind: YaccGrammarErrorKind::UnknownRuleRef(_),
@@ -494,7 +494,7 @@ mod test {
494494
grm.tokens.insert("b".to_string());
495495
grm.start = Some(("A".to_string(), empty_span));
496496
grm.add_rule(("A".to_string(), empty_span), None);
497-
grm.add_prod("A".to_string(), vec![token("b")], None, None, None);
497+
grm.add_prod("A".to_string(), vec![token("b")], None, None, empty_span);
498498
assert!(grm.complete_and_validate().is_ok());
499499
}
500500

@@ -507,7 +507,7 @@ mod test {
507507
grm.tokens.insert("b".to_string());
508508
grm.start = Some(("A".to_string(), empty_span));
509509
grm.add_rule(("A".to_string(), empty_span), None);
510-
grm.add_prod("A".to_string(), vec![rule("b")], None, None, None);
510+
grm.add_prod("A".to_string(), vec![rule("b")], None, None, empty_span);
511511
assert!(grm.complete_and_validate().is_err());
512512
}
513513

@@ -517,7 +517,7 @@ mod test {
517517
let empty_span = Span::new(0, 0);
518518
grm.start = Some(("A".to_string(), empty_span));
519519
grm.add_rule(("A".to_string(), empty_span), None);
520-
grm.add_prod("A".to_string(), vec![token("b")], None, None, None);
520+
grm.add_prod("A".to_string(), vec![token("b")], None, None, empty_span);
521521
match grm.complete_and_validate() {
522522
Err(YaccGrammarError {
523523
kind: YaccGrammarErrorKind::UnknownToken(_),
@@ -538,7 +538,7 @@ mod test {
538538
vec![rule("b"), token("b")],
539539
None,
540540
None,
541-
None,
541+
Span::new(0, 2),
542542
);
543543
match grm.complete_and_validate() {
544544
Err(YaccGrammarError {
@@ -555,7 +555,7 @@ mod test {
555555
let empty_span = Span::new(2, 3);
556556
grm.start = Some(("A".to_string(), empty_span));
557557
grm.add_rule(("A".to_string(), empty_span), None);
558-
grm.add_prod("A".to_string(), vec![], None, None, None);
558+
grm.add_prod("A".to_string(), vec![], None, None, empty_span);
559559
grm.epp
560560
.insert("k".to_owned(), (empty_span, ("v".to_owned(), empty_span)));
561561
match grm.complete_and_validate() {
@@ -589,7 +589,7 @@ mod test {
589589
vec![token("b")],
590590
Some("b".to_string()),
591591
None,
592-
None,
592+
empty_span,
593593
);
594594
assert!(grm.complete_and_validate().is_ok());
595595
}
@@ -605,7 +605,7 @@ mod test {
605605
vec![token("b")],
606606
Some("b".to_string()),
607607
None,
608-
None,
608+
empty_span,
609609
);
610610
match grm.complete_and_validate() {
611611
Err(YaccGrammarError {
@@ -630,11 +630,11 @@ mod test {
630630
let empty_span = Span::new(0, 0);
631631
grm.start = Some(("A".to_string(), empty_span));
632632
grm.add_rule(("A".to_string(), empty_span), None);
633-
grm.add_prod("A".to_string(), vec![], None, None, None);
633+
grm.add_prod("A".to_string(), vec![], None, None, empty_span);
634634
grm.tokens.insert("b".to_string());
635635
grm.spans.push(Span::new(4, 5));
636636
grm.add_rule(("B".to_string(), Span::new(1, 2)), None);
637-
grm.add_prod("B".to_string(), vec![token("b")], None, None, None);
637+
grm.add_prod("B".to_string(), vec![token("b")], None, None, empty_span);
638638

639639
assert_eq!(
640640
grm.unused_symbols()

cfgrammar/src/lib/yacc/parser.rs

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,6 @@ impl YaccParser {
759759
}
760760

761761
fn parse_rule(&mut self, mut i: usize) -> Result<usize, YaccGrammarError> {
762-
let mut empty_span: Option<Span> = None;
763762
let (j, rn) = self.parse_name(i)?;
764763
let span = Span::new(i, j);
765764
if self.ast.start.is_none() {
@@ -802,31 +801,37 @@ impl YaccParser {
802801
let mut prec = None;
803802
let mut action = None;
804803
i = self.parse_ws(i, true)?;
804+
let mut pos_prod_start = i;
805+
let mut pos_prod_end = None;
805806
while i < self.src.len() {
806807
if let Some(j) = self.lookahead_is("|", i) {
807-
let span = if syms.is_empty() {
808-
empty_span.take().or(Some(Span::new(i, i)))
809-
} else {
810-
None
811-
};
812-
self.ast.add_prod(rn.clone(), syms, prec, action, span);
808+
self.ast.add_prod(
809+
rn.clone(),
810+
syms,
811+
prec,
812+
action,
813+
Span::new(pos_prod_start, pos_prod_end.take().unwrap_or(i)),
814+
);
813815
syms = Vec::new();
814816
prec = None;
815817
action = None;
816818
i = self.parse_ws(j, true)?;
819+
pos_prod_start = i;
817820
continue;
818821
} else if let Some(j) = self.lookahead_is(";", i) {
819-
let empty_span = if syms.is_empty() {
820-
empty_span.take().or(Some(Span::new(i, i)))
821-
} else {
822-
None
823-
};
824-
self.ast.add_prod(rn, syms, prec, action, empty_span);
822+
self.ast.add_prod(
823+
rn,
824+
syms,
825+
prec,
826+
action,
827+
Span::new(pos_prod_start, pos_prod_end.take().unwrap_or(i)),
828+
);
825829
return Ok(j);
826830
}
827831

828832
if self.lookahead_is("\"", i).is_some() || self.lookahead_is("'", i).is_some() {
829833
let (j, sym, span) = self.parse_token(i)?;
834+
pos_prod_end = Some(j);
830835
i = self.parse_ws(j, true)?;
831836
if self.ast.tokens.insert(sym.clone()) {
832837
self.ast.spans.push(span);
@@ -839,8 +844,10 @@ impl YaccParser {
839844
self.ast.spans.push(span);
840845
}
841846
prec = Some(sym);
847+
pos_prod_end = Some(k);
842848
i = k;
843849
} else if self.lookahead_is("{", i).is_some() {
850+
pos_prod_end = Some(i);
844851
let (j, a) = self.parse_action(i)?;
845852
i = self.parse_ws(j, true)?;
846853
action = Some(a);
@@ -860,10 +867,11 @@ impl YaccParser {
860867
{
861868
return Err(self.mk_error(YaccGrammarErrorKind::NonEmptyProduction, i));
862869
}
863-
empty_span = Some(Span::new(i, j));
870+
pos_prod_end = Some(j);
864871
i = k;
865872
} else {
866873
let (j, sym, span) = self.parse_token(i)?;
874+
pos_prod_end = Some(j);
867875
if self.ast.tokens.contains(&sym) {
868876
syms.push(Symbol::Token(sym, span));
869877
} else {
@@ -1335,7 +1343,7 @@ mod test {
13351343
symbols: vec![token_span("a", a_span)],
13361344
precedence: None,
13371345
action: None,
1338-
empty_span: None,
1346+
prod_span: Span::new(32, 35),
13391347
}
13401348
);
13411349
assert_eq!(&src[a_span.start()..a_span.end()], "a");
@@ -1361,7 +1369,7 @@ mod test {
13611369
symbols: vec![token_span("a", a_span)],
13621370
precedence: None,
13631371
action: None,
1364-
empty_span: None,
1372+
prod_span: Span::new(32, 35),
13651373
}
13661374
);
13671375
assert_eq!(&src[a_span.start()..a_span.end()], "a");
@@ -1372,7 +1380,7 @@ mod test {
13721380
symbols: vec![token_span("b", Span::new(54, 55))],
13731381
precedence: None,
13741382
action: None,
1375-
empty_span: None,
1383+
prod_span: Span::new(53, 56),
13761384
}
13771385
);
13781386
assert_eq!(&src[b_span.start()..b_span.end()], "b");
@@ -1399,7 +1407,7 @@ mod test {
13991407
symbols: vec![],
14001408
precedence: None,
14011409
action: None,
1402-
empty_span: Some(Span::new(32, 32)),
1410+
prod_span: Span::new(32, 32),
14031411
}
14041412
);
14051413

@@ -1410,7 +1418,7 @@ mod test {
14101418
symbols: vec![token_span("b", b_span)],
14111419
precedence: None,
14121420
action: None,
1413-
empty_span: None,
1421+
prod_span: Span::new(50, 53),
14141422
}
14151423
);
14161424
assert_eq!(&src[b_span.start()..b_span.end()], "b");
@@ -1420,7 +1428,7 @@ mod test {
14201428
symbols: vec![],
14211429
precedence: None,
14221430
action: None,
1423-
empty_span: Some(Span::new(56, 56)),
1431+
prod_span: Span::new(56, 56),
14241432
}
14251433
);
14261434

@@ -1430,7 +1438,7 @@ mod test {
14301438
symbols: vec![],
14311439
precedence: None,
14321440
action: None,
1433-
empty_span: Some(Span::new(74, 74)),
1441+
prod_span: Span::new(74, 74),
14341442
}
14351443
);
14361444
let c_span = Span::new(77, 78);
@@ -1440,7 +1448,7 @@ mod test {
14401448
symbols: vec![token_span("c", c_span)],
14411449
precedence: None,
14421450
action: None,
1443-
empty_span: None,
1451+
prod_span: Span::new(76, 79),
14441452
}
14451453
);
14461454
assert_eq!(&src[c_span.start()..c_span.end()], "c");
@@ -1472,7 +1480,7 @@ mod test {
14721480
symbols: vec![token_span("a", a_span), rule_span("B", b_span)],
14731481
precedence: None,
14741482
action: None,
1475-
empty_span: None,
1483+
prod_span: Span::new(7, 12),
14761484
}
14771485
);
14781486
assert_eq!(&src[a_span.start()..a_span.end()], "a");
@@ -1495,7 +1503,7 @@ mod test {
14951503
symbols: vec![token_span("a", a_span), token_span("b", b_span)],
14961504
precedence: None,
14971505
action: None,
1498-
empty_span: None,
1506+
prod_span: Span::new(7, 14),
14991507
}
15001508
);
15011509
assert_eq!(&src[a_span.start()..a_span.end()], "a");
@@ -1575,7 +1583,7 @@ mod test {
15751583
symbols: vec![token_span("T", t_span)],
15761584
precedence: None,
15771585
action: None,
1578-
empty_span: None,
1586+
prod_span: t_span,
15791587
}
15801588
);
15811589
assert_eq!(&src[t_span.start()..t_span.end() + 1], "T;");
@@ -2838,31 +2846,31 @@ B";
28382846
Expr: %empty | Factor;
28392847
Factor: ')' Expr ')';
28402848
",
2841-
(0, Some(Span::new(21, 27))),
2849+
(0, Span::new(21, 27)),
28422850
),
28432851
(
28442852
"%start Expr
28452853
%%
28462854
Expr: | Factor;
28472855
Factor: ')' Expr ')';
28482856
",
2849-
(0, Some(Span::new(21, 21))),
2857+
(0, Span::new(21, 21)),
28502858
),
28512859
(
28522860
"%start Expr
28532861
%%
28542862
Expr: Factor | %empty;
28552863
Factor: ')' Expr ')';
28562864
",
2857-
(1, Some(Span::new(30, 36))),
2865+
(1, Span::new(30, 36)),
28582866
),
28592867
(
28602868
"%start Expr
28612869
%%
28622870
Expr: Factor | ;
28632871
Factor: ')' Expr ')';
28642872
",
2865-
(1, Some(Span::new(30, 30))),
2873+
(1, Span::new(30, 30)),
28662874
),
28672875
];
28682876

@@ -2875,7 +2883,7 @@ Factor: ')' Expr ')';
28752883
symbols: vec![],
28762884
precedence: None,
28772885
action: None,
2878-
empty_span: *empty_span,
2886+
prod_span: *empty_span,
28792887
}
28802888
);
28812889
}

nimbleparse/src/diagnostics.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ impl<'a> SpannedDiagnosticFormatter<'a> {
276276
let shift_name = grm.token_name(*s_tok_idx).unwrap();
277277
let reduce_name = grm.rule_name_str(r_rule_idx);
278278
let (_r_prod_names, mut r_prod_spans) = pidx_prods_data(ast, *r_prod_idx);
279-
let fallback_span = ast.prods[usize::from(*r_prod_idx)].empty_span;
279+
let fallback_span = ast.prods[usize::from(*r_prod_idx)].prod_span;
280280
eprintln!(
281281
"{}",
282282
self.file_location_msg(
@@ -298,9 +298,8 @@ impl<'a> SpannedDiagnosticFormatter<'a> {
298298
self.underline_span_with_text(r_rule_span, "Reduced rule".to_string(), '+')
299299
);
300300

301-
assert!((!r_prod_spans.is_empty()) || fallback_span.is_some());
302301
if r_prod_spans.is_empty() {
303-
r_prod_spans.push(fallback_span.unwrap());
302+
r_prod_spans.push(fallback_span);
304303
}
305304

306305
let mut prod_lines = r_prod_spans

0 commit comments

Comments
 (0)