1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
4 // Performs the dynamic replacement of arcs in one FST with another FST,
5 // allowing for the definition of FSTs analogous to RTNs.
12 #include <fst/script/getters.h>
13 #include <fst/script/replace.h>
15 DEFINE_string(call_arc_labeling, "input",
16 "Which labels to make non-epsilon on the call arc. "
17 "One of: \"input\" (default), \"output\", \"both\", \"neither\"");
18 DEFINE_string(return_arc_labeling, "neither",
19 "Which labels to make non-epsilon on the return arc. "
20 "One of: \"input\", \"output\", \"both\", \"neither\" (default)");
21 DEFINE_int64(return_label, 0, "Label to put on return arc");
22 DEFINE_bool(epsilon_on_replace, false, "Call/return arcs are epsilon arcs?");
24 int main(int argc, char **argv) {
25 namespace s = fst::script;
26 using fst::script::FstClass;
27 using fst::script::VectorFstClass;
28 using fst::ReplaceLabelType;
30 string usage = "Recursively replaces FST arcs with other FST(s).\n\n"
33 usage += " root.fst rootlabel [rule1.fst label1 ...] [out.fst]\n";
35 std::set_new_handler(FailedNewHandler);
36 SET_FLAGS(usage.c_str(), &argc, &argv, true);
42 const string in_name = argv[1];
43 const string out_name = argc % 2 == 0 ? argv[argc - 1] : "";
45 // Replace takes ownership of the pointer of FST arrays, deleting all such
46 // pointers when the underlying ReplaceFst is destroyed.
47 auto *ifst = FstClass::Read(in_name);
50 std::vector<s::LabelFstClassPair> pairs;
51 // Note that if the root label is beyond the range of the underlying FST's
52 // labels, truncation will occur.
53 const auto root = atoll(argv[2]);
54 pairs.emplace_back(root, ifst);
56 for (auto i = 3; i < argc - 1; i += 2) {
57 ifst = FstClass::Read(argv[i]);
59 // Note that if the root label is beyond the range of the underlying FST's
60 // labels, truncation will occur.
61 const auto label = atoll(argv[i + 1]);
62 pairs.emplace_back(label, ifst);
65 ReplaceLabelType call_label_type;
66 if (!s::GetReplaceLabelType(FLAGS_call_arc_labeling, FLAGS_epsilon_on_replace,
68 LOG(ERROR) << argv[0] << ": Unknown or unsupported call arc replace "
69 << "label type: " << FLAGS_call_arc_labeling;
71 ReplaceLabelType return_label_type;
72 if (!s::GetReplaceLabelType(FLAGS_return_arc_labeling,
73 FLAGS_epsilon_on_replace, &return_label_type)) {
74 LOG(ERROR) << argv[0] << ": Unknown or unsupported return arc replace "
75 << "label type: " << FLAGS_return_arc_labeling;
78 s::ReplaceOptions opts(root, call_label_type, return_label_type,
81 VectorFstClass ofst(ifst->ArcType());
82 s::Replace(pairs, &ofst, opts);
84 return !ofst.Write(out_name);