Skip to content
Closed
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
25 changes: 16 additions & 9 deletions cfgrammar/src/lib/yacc/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ 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: YaccKind,
ast: GrammarAST,
errs: Vec<YaccGrammarError>,
}
Expand All @@ -25,16 +26,18 @@ impl ASTWithValidityInfo {
/// `Ok(YaccGrammar)` or an `Err` which includes these errors.
pub fn new(yacc_kind: YaccKind, 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();
ast.complete_and_validate().map_err(|e| errs.push(e)).ok();
ast
}
let (ast, yacc_kind) = {
let mut yp = YaccParser::new(yacc_kind, s.to_string());
yp.parse().map_err(|e| errs.extend(e)).ok();
let (yacc_kind, mut ast) = yp.finish();
ast.complete_and_validate().map_err(|e| errs.push(e)).ok();
(ast, yacc_kind)
};
ASTWithValidityInfo { ast, errs }
ASTWithValidityInfo {
ast,
errs,
yacc_kind,
}
}

/// Returns a `GrammarAST` constructed as the result of parsing a source file.
Expand All @@ -55,6 +58,10 @@ impl ASTWithValidityInfo {
pub fn errors(&self) -> &[YaccGrammarError] {
self.errs.as_slice()
}

pub fn yacc_kind(&self) -> &YaccKind {
&self.yacc_kind
}
}

/// An AST representing a grammar. This is built up gradually: when it is finished, the
Expand Down
10 changes: 6 additions & 4 deletions cfgrammar/src/lib/yacc/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,11 @@ where
/// though the actual name is a fresh name that is guaranteed to be unique) that references the
/// user defined start rule.
pub fn new_with_storaget(yacc_kind: YaccKind, s: &str) -> YaccGrammarResult<Self> {
let ast_validation = ast::ASTWithValidityInfo::new(yacc_kind, s);
Self::new_from_ast_with_validity_info(yacc_kind, &ast_validation)
let ast_validation = ast::ASTWithValidityInfo::new(yacc_kind.clone(), s);
Self::new_from_ast_with_validity_info(&ast_validation)
}

pub fn new_from_ast_with_validity_info(
yacc_kind: YaccKind,
ast_validation: &ast::ASTWithValidityInfo,
) -> YaccGrammarResult<Self> {
if !ast_validation.is_valid() {
Expand Down Expand Up @@ -149,7 +148,10 @@ where

let implicit_rule;
let implicit_start_rule;
match yacc_kind {
match ast_validation.yacc_kind() {
YaccKind::SelfDescribing(_) => {
unimplemented!("Concrete YaccKind must be known by this point")
}
YaccKind::Original(_) | YaccKind::Grmtools => {
implicit_rule = None;
implicit_start_rule = None;
Expand Down
17 changes: 16 additions & 1 deletion cfgrammar/src/lib/yacc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub use self::{
use serde::{Deserialize, Serialize};

/// The particular Yacc variant this grammar makes use of.
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum YaccKind {
/// The original Yacc style as documented by
Expand All @@ -26,6 +26,21 @@ pub enum YaccKind {
Grmtools,
/// The variant used in the [Eco language composition editor](http://soft-dev.org/src/eco/)
Eco,
/// A `SelfDescribing` grammar starts with an initial `%grmtools` directive specifying it's
/// yacckind.
///
/// For example:
/// ``` yacc
/// %grmtools {
/// yacckind Original(NoAction)
/// }
/// ...
/// ```
///
/// The `Option<Box<YaccKind>>` value if specified will be used as the default format.
/// If the default kind is `None` and the file does not specify a yacc kind produce a
/// `MissingYaccKind` error.
SelfDescribing(Option<Box<YaccKind>>),
}

#[derive(Clone, Copy, Debug)]
Expand Down
Loading