FST  openfst-1.7.3
OpenFst Library
fstreplace-main.cc
Go to the documentation of this file.
1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
3 //
4 // Performs the dynamic replacement of arcs in one FST with another FST,
5 // allowing for the definition of FSTs analogous to RTNs.
6 
7 #include <cstring>
8 #include <string>
9 #include <vector>
10 
11 #include <fst/flags.h>
12 #include <fst/script/getters.h>
13 #include <fst/script/replace.h>
14 
15 DECLARE_string(call_arc_labeling);
16 DECLARE_string(return_arc_labeling);
17 DECLARE_int64(return_label);
18 DECLARE_bool(epsilon_on_replace);
19 
20 void Cleanup(std::vector<fst::script::LabelFstClassPair> *pairs) {
21  for (const auto &pair : *pairs) {
22  delete pair.second;
23  }
24  pairs->clear();
25 }
26 
27 int fstreplace_main(int argc, char **argv) {
28  namespace s = fst::script;
32 
33  std::string usage =
34  "Recursively replaces FST arcs with other FST(s).\n\n"
35  " Usage: ";
36  usage += argv[0];
37  usage += " root.fst rootlabel [rule1.fst label1 ...] [out.fst]\n";
38 
39  std::set_new_handler(FailedNewHandler);
40  SET_FLAGS(usage.c_str(), &argc, &argv, true);
41  if (argc < 4) {
42  ShowUsage();
43  return 1;
44  }
45 
46  const std::string in_name = argv[1];
47  const std::string out_name = argc % 2 == 0 ? argv[argc - 1] : "";
48 
49  auto *ifst = FstClass::Read(in_name);
50  if (!ifst) return 1;
51 
52  std::vector<s::LabelFstClassPair> pairs;
53  // Note that if the root label is beyond the range of the underlying FST's
54  // labels, truncation will occur.
55  const auto root = atoll(argv[2]);
56  pairs.emplace_back(root, ifst);
57 
58  for (auto i = 3; i < argc - 1; i += 2) {
59  ifst = FstClass::Read(argv[i]);
60  if (!ifst) {
61  Cleanup(&pairs);
62  return 1;
63  }
64  // Note that if the root label is beyond the range of the underlying FST's
65  // labels, truncation will occur.
66  const auto label = atoll(argv[i + 1]);
67  pairs.emplace_back(label, ifst);
68  }
69 
70  ReplaceLabelType call_label_type;
71  if (!s::GetReplaceLabelType(FLAGS_call_arc_labeling, FLAGS_epsilon_on_replace,
72  &call_label_type)) {
73  LOG(ERROR) << argv[0] << ": Unknown or unsupported call arc replace "
74  << "label type: " << FLAGS_call_arc_labeling;
75  }
76  ReplaceLabelType return_label_type;
77  if (!s::GetReplaceLabelType(FLAGS_return_arc_labeling,
78  FLAGS_epsilon_on_replace, &return_label_type)) {
79  LOG(ERROR) << argv[0] << ": Unknown or unsupported return arc replace "
80  << "label type: " << FLAGS_return_arc_labeling;
81  }
82 
83  s::ReplaceOptions opts(root, call_label_type, return_label_type,
84  FLAGS_return_label);
85 
86  VectorFstClass ofst(ifst->ArcType());
87  s::Replace(pairs, &ofst, opts);
88  Cleanup(&pairs);
89 
90  return !ofst.Write(out_name);
91 }
void ShowUsage(bool long_usage=true)
Definition: flags.cc:121
DECLARE_string(call_arc_labeling)
DECLARE_int64(return_label)
ReplaceLabelType
Definition: replace-util.h:28
#define LOG(type)
Definition: log.h:46
void Replace(const std::vector< std::pair< typename Arc::Label, const Fst< Arc > * >> &ifst_array, MutableFst< Arc > *ofst, std::vector< std::pair< typename Arc::Label, typename Arc::Label >> *parens, const PdtReplaceOptions< Arc > &opts)
Definition: replace.h:786
void FailedNewHandler()
Definition: compat.cc:20
#define SET_FLAGS(usage, argc, argv, rmflags)
Definition: flags.h:209
int fstreplace_main(int argc, char **argv)
void Cleanup(std::vector< fst::script::LabelFstClassPair > *pairs)
DECLARE_bool(epsilon_on_replace)
bool GetReplaceLabelType(const std::string &str, bool epsilon_on_replace, ReplaceLabelType *rlt)
Definition: getters.cc:120