Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions cfgrammar/src/lib/yacc/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ use indexmap::{IndexMap, IndexSet};

use super::{
parser::YaccParser, Precedence, YaccGrammarError, YaccGrammarErrorKind, YaccGrammarWarning,
YaccGrammarWarningKind, YaccKind,
YaccGrammarWarningKind, YaccKind, YaccKindResolver,
};

use crate::Span;
/// Contains a `GrammarAST` structure produced from a grammar source file.
/// As well as any errors which occurred during the construction of the AST.
pub struct ASTWithValidityInfo {
yacc_kind: Option<YaccKind>,
ast: GrammarAST,
errs: Vec<YaccGrammarError>,
}
Expand All @@ -23,18 +24,22 @@ impl ASTWithValidityInfo {
/// encountered during the construction of it. The `ASTWithValidityInfo` can be
/// then unused to construct a `YaccGrammar`, which will either produce an
/// `Ok(YaccGrammar)` or an `Err` which includes these errors.
pub fn new(yacc_kind: YaccKind, s: &str) -> Self {
pub fn new(yacc_kind_resolver: YaccKindResolver, s: &str) -> Self {
let mut errs = Vec::new();
let ast = match yacc_kind {
YaccKind::Original(_) | YaccKind::Grmtools | YaccKind::Eco => {
let mut yp = YaccParser::new(yacc_kind, s.to_string());
yp.parse().map_err(|e| errs.extend(e)).ok();
let mut ast = yp.ast();
let (yacc_kind, ast) = {
let mut yp = YaccParser::new(yacc_kind_resolver, s.to_string());
yp.parse().map_err(|e| errs.extend(e)).ok();
let (yacc_kind, mut ast) = yp.build();
if yacc_kind.is_some() {
ast.complete_and_validate().map_err(|e| errs.push(e)).ok();
ast
}
(yacc_kind, ast)
};
ASTWithValidityInfo { ast, errs }
ASTWithValidityInfo {
ast,
errs,
yacc_kind,
}
}

/// Returns a `GrammarAST` constructed as the result of parsing a source file.
Expand All @@ -51,6 +56,11 @@ impl ASTWithValidityInfo {
self.errors().is_empty()
}

/// Returns the `YaccKind` that was used to parse the `GrammarAST`.
pub fn yacc_kind(&self) -> Option<YaccKind> {
self.yacc_kind
}

/// Returns all errors which were encountered during AST construction.
pub fn errors(&self) -> &[YaccGrammarError] {
self.errs.as_slice()
Expand Down
18 changes: 9 additions & 9 deletions cfgrammar/src/lib/yacc/firsts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{RIdx, Symbol, TIdx};
/// `Firsts` stores all the first sets for a given grammar. For example, given this code and
/// grammar:
/// ```text
/// let grm = YaccGrammar::new(YaccKind::Original(YaccOriginalActionKind::GenericParseTree), "
/// let grm = YaccGrammar::new(YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)), "
/// S: A 'b';
/// A: 'a'
/// | ;").unwrap();
Expand Down Expand Up @@ -143,7 +143,7 @@ where
#[cfg(test)]
mod test {
use super::{
super::{YaccGrammar, YaccKind, YaccOriginalActionKind},
super::{YaccGrammar, YaccKind, YaccKindResolver, YaccOriginalActionKind},
YaccFirsts,
};
use num_traits::{AsPrimitive, PrimInt, Unsigned};
Expand Down Expand Up @@ -180,7 +180,7 @@ mod test {
#[test]
fn test_first() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start C
%token c d
Expand All @@ -202,7 +202,7 @@ mod test {
#[test]
fn test_first_no_subsequent_rules() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start C
%token c d
Expand All @@ -220,7 +220,7 @@ mod test {
#[test]
fn test_first_epsilon() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start A
%token a b c
Expand All @@ -241,7 +241,7 @@ mod test {
#[test]
fn test_last_epsilon() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start A
%token b c
Expand All @@ -261,7 +261,7 @@ mod test {
#[test]
fn test_first_no_multiples() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start A
%token b c
Expand All @@ -277,7 +277,7 @@ mod test {

fn eco_grammar() -> YaccGrammar {
YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start S
%token a b c d f
Expand Down Expand Up @@ -308,7 +308,7 @@ mod test {
#[test]
fn test_first_from_eco_bug() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start E
%token a b c d e f
Expand Down
12 changes: 6 additions & 6 deletions cfgrammar/src/lib/yacc/follows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{RIdx, Symbol, TIdx};
/// `Follows` stores all the Follow sets for a given grammar. For example, given this code and
/// grammar:
/// ```text
/// let grm = YaccGrammar::new(YaccKind::Original(YaccOriginalActionKind::GenericParseTree), "
/// let grm = YaccGrammar::new(YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)), "
/// S: A 'b';
/// A: 'a' | ;
/// ").unwrap();
Expand Down Expand Up @@ -115,7 +115,7 @@ where
#[cfg(test)]
mod test {
use super::{
super::{YaccGrammar, YaccKind, YaccOriginalActionKind},
super::{YaccGrammar, YaccKind, YaccKindResolver, YaccOriginalActionKind},
YaccFollows,
};
use num_traits::{AsPrimitive, PrimInt, Unsigned};
Expand Down Expand Up @@ -149,7 +149,7 @@ mod test {
fn test_follow() {
// Adapted from p2 of https://www.cs.uaf.edu/~cs331/notes/FirstFollow.pdf
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start E
%%
Expand All @@ -173,7 +173,7 @@ mod test {
fn test_follow2() {
// Adapted from https://www.l2f.inesc-id.pt/~david/w/pt/Top-Down_Parsing/Exercise_5:_Test_2010/07/01
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start A
%%
Expand All @@ -196,7 +196,7 @@ mod test {
#[test]
fn test_follow3() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start S
%%
Expand All @@ -213,7 +213,7 @@ mod test {
#[test]
fn test_follow_corchuelo() {
let grm = YaccGrammar::new(
YaccKind::Original(YaccOriginalActionKind::GenericParseTree),
YaccKindResolver::Force(YaccKind::Original(YaccOriginalActionKind::GenericParseTree)),
"
%start E
%%
Expand Down
Loading