FST  openfst-1.8.3
OpenFst Library
print-impl.h
Go to the documentation of this file.
1 // Copyright 2005-2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the 'License');
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an 'AS IS' BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // Stand-alone class to print out binary FSTs in the AT&T format, a helper
19 // class for fstprint.cc.
20 
21 #ifndef FST_SCRIPT_PRINT_IMPL_H_
22 #define FST_SCRIPT_PRINT_IMPL_H_
23 
24 #include <ostream>
25 #include <sstream>
26 #include <string>
27 
28 #include <fst/log.h>
29 #include <fst/fst.h>
30 #include <fst/fstlib.h>
31 #include <fst/properties.h>
32 #include <fst/symbol-table.h>
33 #include <fst/util.h>
34 #include <string_view>
35 
36 namespace fst {
37 
38 // Print a binary FST in textual format (helper class for fstprint.cc).
39 // WARNING: Stand-alone use of this class not recommended, most code should
40 // read/write using the binary format which is much more efficient.
41 template <class Arc>
42 class FstPrinter {
43  public:
44  using StateId = typename Arc::StateId;
45  using Label = typename Arc::Label;
46  using Weight = typename Arc::Weight;
47 
48  explicit FstPrinter(const Fst<Arc> &fst, const SymbolTable *isyms,
49  const SymbolTable *osyms, const SymbolTable *ssyms,
50  bool accept, bool show_weight_one,
51  std::string_view field_separator,
52  std::string_view missing_symbol = "")
53  : fst_(fst),
54  isyms_(isyms),
55  osyms_(osyms),
56  ssyms_(ssyms),
57  accept_(accept && (fst.Properties(kAcceptor, true) == kAcceptor)),
58  show_weight_one_(show_weight_one),
59  sep_(field_separator),
60  missing_symbol_(missing_symbol) {}
61 
62  // Prints FST to an output stream.
63  void Print(std::ostream &ostrm, std::string_view dest) {
64  dest_ = std::string(dest);
65  const auto start = fst_.Start();
66  if (start == kNoStateId) return;
67  // Initial state first.
68  PrintState(ostrm, start);
69  for (StateIterator<Fst<Arc>> siter(fst_); !siter.Done(); siter.Next()) {
70  const auto s = siter.Value();
71  if (s != start) PrintState(ostrm, s);
72  }
73  }
74 
75  private:
76  std::string FormatId(StateId id, const SymbolTable *syms) const {
77  if (syms) {
78  std::string symbol = syms->Find(id);
79  if (symbol.empty()) {
80  if (missing_symbol_.empty()) {
81  FSTERROR() << "FstPrinter: Integer " << id
82  << " is not mapped to any textual symbol"
83  << ", symbol table = " << syms->Name()
84  << ", destination = " << dest_;
85  symbol = "?";
86  } else {
87  symbol = missing_symbol_;
88  }
89  }
90  return symbol;
91  } else {
92  return std::to_string(id);
93  }
94  }
95 
96  std::string FormatStateId(StateId s) const { return FormatId(s, ssyms_); }
97 
98  std::string FormatILabel(Label l) const { return FormatId(l, isyms_); }
99 
100  std::string FormatOLabel(Label l) const { return FormatId(l, osyms_); }
101 
102  void PrintState(std::ostream &ostrm, StateId s) const {
103  bool output = false;
104  for (ArcIterator<Fst<Arc>> aiter(fst_, s); !aiter.Done(); aiter.Next()) {
105  const auto &arc = aiter.Value();
106  ostrm << FormatStateId(s) << sep_ << FormatStateId(arc.nextstate)
107  << sep_ << FormatILabel(arc.ilabel);
108  if (!accept_) {
109  ostrm << sep_ << FormatOLabel(arc.olabel);
110  }
111  if (show_weight_one_ || arc.weight != Weight::One()) {
112  ostrm << sep_ << arc.weight;
113  }
114  ostrm << "\n";
115  output = true;
116  }
117  const auto weight = fst_.Final(s);
118  if (weight != Weight::Zero() || !output) {
119  ostrm << FormatStateId(s);
120  if (show_weight_one_ || weight != Weight::One()) {
121  ostrm << sep_ << weight;
122  }
123  ostrm << "\n";
124  }
125  }
126 
127  const Fst<Arc> &fst_;
128  const SymbolTable *isyms_; // ilabel symbol table.
129  const SymbolTable *osyms_; // olabel symbol table.
130  const SymbolTable *ssyms_; // slabel symbol table.
131  bool accept_; // Print as acceptor when possible?
132  std::string dest_; // Text FST destination name.
133  bool show_weight_one_; // Print weights equal to Weight::One()?
134  std::string sep_; // Separator character between fields.
135  std::string missing_symbol_; // Symbol to print when lookup fails (default
136  // "" means raise error).
137 
138  FstPrinter(const FstPrinter &) = delete;
139  FstPrinter &operator=(const FstPrinter &) = delete;
140 };
141 
142 } // namespace fst
143 
144 #endif // FST_SCRIPT_PRINT_IMPL_H_
const std::string & Name() const
Definition: symbol-table.h:466
typename Arc::StateId StateId
Definition: print-impl.h:44
virtual Weight Final(StateId) const =0
constexpr int kNoStateId
Definition: fst.h:196
#define FSTERROR()
Definition: util.h:56
void Print(std::ostream &ostrm, std::string_view dest)
Definition: print-impl.h:63
virtual StateId Start() const =0
FstPrinter(const Fst< Arc > &fst, const SymbolTable *isyms, const SymbolTable *osyms, const SymbolTable *ssyms, bool accept, bool show_weight_one, std::string_view field_separator, std::string_view missing_symbol="")
Definition: print-impl.h:48
typename Arc::Label Label
Definition: print-impl.h:45
typename Arc::Weight Weight
Definition: print-impl.h:46
std::string Find(int64_t key) const
Definition: symbol-table.h:450
constexpr uint64_t kAcceptor
Definition: properties.h:64