1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
4 // Stand-alone class to print out binary FSTs in the AT&T format, a helper
5 // class for fstprint.cc.
7 #ifndef FST_SCRIPT_PRINT_IMPL_H_
8 #define FST_SCRIPT_PRINT_IMPL_H_
14 #include <fst/fstlib.h>
17 DECLARE_string(fst_field_separator);
21 // Print a binary FST in textual format (helper class for fstprint.cc).
22 // WARNING: Stand-alone use of this class not recommended, most code should
23 // read/write using the binary format which is much more efficient.
27 using StateId = typename Arc::StateId;
28 using Label = typename Arc::Label;
29 using Weight = typename Arc::Weight;
31 FstPrinter(const Fst<Arc> &fst, const SymbolTable *isyms,
32 const SymbolTable *osyms, const SymbolTable *ssyms, bool accep,
33 bool show_weight_one, const string &field_separator,
34 const string &missing_symbol = "")
39 accep_(accep && fst.Properties(kAcceptor, true)),
41 show_weight_one_(show_weight_one),
42 sep_(field_separator),
43 missing_symbol_(missing_symbol) {}
45 // Prints FST to an output stream.
46 void Print(std::ostream *ostrm, const string &dest) {
49 const auto start = fst_.Start();
50 if (start == kNoStateId) return;
51 // Initial state first.
53 for (StateIterator<Fst<Arc>> siter(fst_); !siter.Done(); siter.Next()) {
54 const auto s = siter.Value();
55 if (s != start) PrintState(s);
60 void PrintId(StateId id, const SymbolTable *syms, const char *name) const {
62 string symbol = syms->Find(id);
64 if (missing_symbol_ == "") {
65 FSTERROR() << "FstPrinter: Integer " << id
66 << " is not mapped to any textual symbol"
67 << ", symbol table = " << syms->Name()
68 << ", destination = " << dest_;
71 symbol = missing_symbol_;
80 void PrintStateId(StateId s) const { PrintId(s, ssyms_, "state ID"); }
82 void PrintILabel(Label l) const { PrintId(l, isyms_, "arc input label"); }
84 void PrintOLabel(Label l) const { PrintId(l, osyms_, "arc output label"); }
86 void PrintState(StateId s) const {
88 for (ArcIterator<Fst<Arc>> aiter(fst_, s); !aiter.Done(); aiter.Next()) {
89 const auto &arc = aiter.Value();
92 PrintStateId(arc.nextstate);
94 PrintILabel(arc.ilabel);
97 PrintOLabel(arc.olabel);
99 if (show_weight_one_ || arc.weight != Weight::One())
100 *ostrm_ << sep_ << arc.weight;
104 const auto weight = fst_.Final(s);
105 if (weight != Weight::Zero() || !output) {
107 if (show_weight_one_ || weight != Weight::One()) {
108 *ostrm_ << sep_ << weight;
114 const Fst<Arc> &fst_;
115 const SymbolTable *isyms_; // ilabel symbol table.
116 const SymbolTable *osyms_; // olabel symbol table.
117 const SymbolTable *ssyms_; // slabel symbol table.
118 bool accep_; // Print as acceptor when possible?
119 std::ostream *ostrm_; // Text FST destination.
120 string dest_; // Text FST destination name.
121 bool show_weight_one_; // Print weights equal to Weight::One()?
122 string sep_; // Separator character between fields.
123 string missing_symbol_; // Symbol to print when lookup fails (default
124 // "" means raise error).
126 FstPrinter(const FstPrinter &) = delete;
127 FstPrinter &operator=(const FstPrinter &) = delete;
132 #endif // FST_SCRIPT_PRINT_IMPL_H_