Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bring back allow_empty to DSL #870

Merged
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
14 changes: 12 additions & 2 deletions crates/codegen/ebnf/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,17 @@ impl Builder {
let RepeatedItem {
name,
reference,
allow_empty,
enabled,
} = repeated_item;

self.add_entry(name, Terminal::No, Inlined::No);

let expression = Expression::new_one_or_more(Self::build_ref(reference).into());
let expression = if allow_empty.unwrap_or_default() {
Expression::new_zero_or_more(Self::build_ref(reference).into())
} else {
Expression::new_one_or_more(Self::build_ref(reference).into())
};

self.add_definition(
name,
Expand All @@ -165,12 +170,13 @@ impl Builder {
name,
reference,
separator,
allow_empty,
enabled,
} = separated_item;

self.add_entry(name, Terminal::No, Inlined::No);

let expression = Expression::new_sequence(vec![
let mut expression = Expression::new_sequence(vec![
Self::build_ref(reference),
Expression::new_zero_or_more(
Expression::new_sequence(vec![
Expand All @@ -181,6 +187,10 @@ impl Builder {
),
]);

if allow_empty.unwrap_or_default() {
expression = Expression::new_optional(expression.into());
}

self.add_definition(
name,
Self::build_enabled_comment(enabled),
Expand Down
20 changes: 15 additions & 5 deletions crates/codegen/grammar/src/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,19 +658,29 @@ fn resolve_choice(item: model::EnumItem, ctx: &mut ResolveCtx<'_>) -> ParserDefi
fn resolve_repeated(item: model::RepeatedItem, ctx: &mut ResolveCtx<'_>) -> ParserDefinitionNode {
let reference = Box::new(resolve_grammar_element(&item.reference, ctx).into_parser_def_node());

ParserDefinitionNode::OneOrMore(Labeled::with_builtin_label(BuiltInLabel::Item, reference))
.versioned(item.enabled)
let repeated = Labeled::with_builtin_label(BuiltInLabel::Item, reference);

if item.allow_empty.unwrap_or_default() {
ParserDefinitionNode::ZeroOrMore(repeated).versioned(item.enabled)
} else {
ParserDefinitionNode::OneOrMore(repeated).versioned(item.enabled)
}
}

fn resolve_separated(item: model::SeparatedItem, ctx: &mut ResolveCtx<'_>) -> ParserDefinitionNode {
let reference = resolve_grammar_element(&item.reference, ctx).into_parser_def_node();
let separator = resolve_grammar_element(&item.separator, ctx).into_parser_def_node();

ParserDefinitionNode::SeparatedBy(
let separated = ParserDefinitionNode::SeparatedBy(
Labeled::with_builtin_label(BuiltInLabel::Item, Box::new(reference)),
Labeled::with_builtin_label(BuiltInLabel::Separator, Box::new(separator)),
)
.versioned(item.enabled)
);

if item.allow_empty.unwrap_or_default() {
ParserDefinitionNode::Optional(Box::new(separated)).versioned(item.enabled)
} else {
separated.versioned(item.enabled)
}
}

fn resolve_precedence(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ fn check_repeated(analysis: &mut Analysis, item: &SpannedRepeatedItem, enablemen
let SpannedRepeatedItem {
name,
reference,
allow_empty: _,
enabled,
} = item;

Expand All @@ -136,6 +137,7 @@ fn check_separated(analysis: &mut Analysis, item: &SpannedSeparatedItem, enablem
name,
reference,
separator,
allow_empty: _,
enabled,
} = item;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ pub struct RepeatedItem {
pub reference: Identifier,

pub enabled: Option<VersionSpecifier>,

pub allow_empty: Option<bool>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ pub struct SeparatedItem {
pub separator: Identifier,

pub enabled: Option<VersionSpecifier>,

pub allow_empty: Option<bool>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,24 +221,26 @@ pub fn select_separated(
let mut separated = vec![];
let mut separators = vec![];

separated.push(self.select(|node| {
if let Some(first) = self.try_select(|node| {
{%- if separated.is_terminal -%}
node.is_token_with_kind(TokenKind::{{ separated.reference }})
{%- else -%}
node.is_rule_with_kind(RuleKind::{{ separated.reference }})
{%- endif -%}
})?);

while let Some(separator) = self.try_select(|node| node.is_token_with_kind(TokenKind::{{ separated.separator }}))? {
separators.push(separator);

separated.push(self.select(|node| {
{%- if separated.is_terminal -%}
node.is_token_with_kind(TokenKind::{{ separated.reference }})
{%- else -%}
node.is_rule_with_kind(RuleKind::{{ separated.reference }})
{%- endif -%}
})?);
})? {
separated.push(first);

while let Some(separator) = self.try_select(|node| node.is_token_with_kind(TokenKind::{{ separated.separator }}))? {
separators.push(separator);

separated.push(self.select(|node| {
{%- if separated.is_terminal -%}
node.is_token_with_kind(TokenKind::{{ separated.reference }})
{%- else -%}
node.is_rule_with_kind(RuleKind::{{ separated.reference }})
{%- endif -%}
})?);
}
}

Ok(vec![separated, separators])
Expand Down
Loading