Skip to content

Commit

Permalink
skip compilation of cursors on source side, anchors on target side
Browse files Browse the repository at this point in the history
  • Loading branch information
skius committed Aug 9, 2023
1 parent 54b0542 commit 8fa4dfd
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
44 changes: 28 additions & 16 deletions experimental/transliterator_parser/src/compile/pass2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ impl<'a, 'p> Pass2<'a, 'p> {

let mut compiled_conversion_group = Vec::new();
for rule in conversion_group {
// TODO: depending on source or target, remove the ignored special constructs (anchor, cursor)
let ante = self.compile_section(rule.ante);
let key = self.compile_section(rule.key);
let post = self.compile_section(rule.post);
let replacer = self.compile_section(rule.replacement);
let ante = self.compile_section(rule.ante, parse::ElementLocation::Source);
let key = self.compile_section(rule.key, parse::ElementLocation::Source);
let post = self.compile_section(rule.post, parse::ElementLocation::Source);
let replacer =
self.compile_section(rule.replacement, parse::ElementLocation::Target);
let cursor_offset = rule.cursor_offset;
compiled_conversion_group.push(ds::Rule {
ante: ante.into(),
Expand All @@ -246,7 +246,7 @@ impl<'a, 'p> Pass2<'a, 'p> {
}

let res = ds::RuleBasedTransliterator {
visibility: true,
visibility: true, // TODO(#3736): use metadata
filter: global_filter
.map(|f| f.code_points().clone())
.unwrap_or(CodePointInversionList::all()),
Expand Down Expand Up @@ -279,30 +279,42 @@ impl<'a, 'p> Pass2<'a, 'p> {
// the first pass ensures that all variables are defined
#[allow(clippy::indexing_slicing)]
let definition = self.var_definitions[var];
let compiled = self.compile_section(definition);
let compiled = self.compile_section(definition, parse::ElementLocation::VariableDefinition);
let standin = self.var_table.insert_compound(compiled);
self.var_to_char.insert(var.to_owned(), standin);
standin
}

fn compile_section(&mut self, section: &'p [parse::Element]) -> String {
fn compile_section(
&mut self,
section: &'p [parse::Element],
loc: parse::ElementLocation,
) -> String {
let mut result = String::new();
for elt in section {
match self.compile_element(elt) {
if elt.kind().skipped_in(loc) {
continue;
}
match self.compile_element(elt, loc) {
LiteralOrStandin::Literal(s) => result.push_str(s),
LiteralOrStandin::Standin(c) => result.push(c),
}
}
result
}

fn compile_element(&mut self, elt: &'p parse::Element) -> LiteralOrStandin<'p> {
fn compile_element(
&mut self,
elt: &'p parse::Element,
loc: parse::ElementLocation,
) -> LiteralOrStandin<'p> {
debug_assert!(!elt.kind().skipped_in(loc));
match elt {
parse::Element::Literal(s) => LiteralOrStandin::Literal(s),
parse::Element::VariableRef(v) => LiteralOrStandin::Standin(self.compile_variable(v)),
parse::Element::Quantifier(q, inner) => {
let inner = self.compile_element(inner).to_string();
let standin = match q {
parse::Element::Quantifier(kind, inner) => {
let inner = self.compile_element(inner, loc).to_string();
let standin = match kind {
parse::QuantifierKind::ZeroOrOne => self.var_table.insert_quantifier_opt(inner),
parse::QuantifierKind::ZeroOrMore => {
self.var_table.insert_quantifier_kleene(inner)
Expand All @@ -327,12 +339,12 @@ impl<'a, 'p> Pass2<'a, 'p> {
LiteralOrStandin::Standin(standin)
}
parse::Element::Segment(inner) => {
let inner = self.compile_section(inner);
let inner = self.compile_section(inner, loc);
let standin = self.var_table.insert_segment(inner);
LiteralOrStandin::Standin(standin)
}
parse::Element::FunctionCall(id, inner) => {
let inner = self.compile_section(inner);
let inner = self.compile_section(inner, loc);
let id = self.compile_single_id(id);
let standin = self.var_table.insert_function_call(ds::FunctionCall {
translit: id,
Expand All @@ -341,7 +353,7 @@ impl<'a, 'p> Pass2<'a, 'p> {
LiteralOrStandin::Standin(standin)
}
parse::Element::Cursor(..) => {
// TODO: compile this in some other step
// TODO(#3736): compile this
LiteralOrStandin::Literal("")
}
}
Expand Down
12 changes: 12 additions & 0 deletions experimental/transliterator_parser/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ pub enum ElementKind {
AnchorEnd,
}

impl ElementKind {
// returns true if the element has no effect in the location. this is not equivalent to
// syntactically being allowed in that location.
pub(crate) fn skipped_in(self, location: ElementLocation) -> bool {
match (location, self) {
(ElementLocation::Source, Self::Cursor) => true,
(ElementLocation::Target, Self::AnchorStart | Self::AnchorEnd) => true,
_ => false,
}
}
}

/// The location in which an element can appear. Used for error reporting in [`ParseError`].
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
Expand Down

0 comments on commit 8fa4dfd

Please sign in to comment.