Home | History | Annotate | Download | only in script
      1 // print.h
      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 // Copyright 2005-2010 Google, Inc.
     16 // Author: riley (at) google.com (Michael Riley)
     17 //
     18 // \file
     19 // Stand-alone class to print out binary FSTs in the AT&T format,
     20 // helper class for fstprint.cc
     21 
     22 #ifndef FST_SCRIPT_PRINT_IMPL_H_
     23 #define FST_SCRIPT_PRINT_IMPL_H_
     24 
     25 #include <sstream>
     26 #include <string>
     27 
     28 #include <fst/fst.h>
     29 #include <fst/util.h>
     30 
     31 DECLARE_string(fst_field_separator);
     32 
     33 namespace fst {
     34 
     35 // Print a binary Fst in textual format, helper class for fstprint.cc
     36 // WARNING: Stand-alone use of this class not recommended, most code should
     37 // read/write using the binary format which is much more efficient.
     38 template <class A> class FstPrinter {
     39  public:
     40   typedef A Arc;
     41   typedef typename A::StateId StateId;
     42   typedef typename A::Label Label;
     43   typedef typename A::Weight Weight;
     44 
     45   FstPrinter(const Fst<A> &fst,
     46              const SymbolTable *isyms,
     47              const SymbolTable *osyms,
     48              const SymbolTable *ssyms,
     49              bool accep,
     50              bool show_weight_one)
     51       : fst_(fst), isyms_(isyms), osyms_(osyms), ssyms_(ssyms),
     52         accep_(accep && fst.Properties(kAcceptor, true)), ostrm_(0),
     53         show_weight_one_(show_weight_one) {}
     54 
     55   // Print Fst to an output stream
     56   void Print(ostream *ostrm, const string &dest) {
     57     ostrm_ = ostrm;
     58     dest_ = dest;
     59     StateId start = fst_.Start();
     60     if (start == kNoStateId)
     61       return;
     62     // initial state first
     63     PrintState(start);
     64     for (StateIterator< Fst<A> > siter(fst_);
     65          !siter.Done();
     66          siter.Next()) {
     67       StateId s = siter.Value();
     68       if (s != start)
     69         PrintState(s);
     70     }
     71   }
     72 
     73  private:
     74   // Maximum line length in text file.
     75   static const int kLineLen = 8096;
     76 
     77   void PrintId(int64 id, const SymbolTable *syms,
     78                const char *name) const {
     79     if (syms) {
     80       string symbol = syms->Find(id);
     81       if (symbol == "") {
     82         FSTERROR() << "FstPrinter: Integer " << id
     83                    << " is not mapped to any textual symbol"
     84                    << ", symbol table = " << syms->Name()
     85                    << ", destination = " << dest_;
     86         symbol = "?";
     87       }
     88       *ostrm_ << symbol;
     89     } else {
     90       *ostrm_ << id;
     91     }
     92   }
     93 
     94   void PrintStateId(StateId s) const {
     95      PrintId(s, ssyms_, "state ID");
     96   }
     97 
     98   void PrintILabel(Label l) const {
     99      PrintId(l, isyms_, "arc input label");
    100   }
    101 
    102   void PrintOLabel(Label l) const {
    103      PrintId(l, osyms_, "arc output label");
    104   }
    105 
    106   void PrintState(StateId s) const {
    107     bool output = false;
    108     for (ArcIterator< Fst<A> > aiter(fst_, s);
    109          !aiter.Done();
    110          aiter.Next()) {
    111       Arc arc = aiter.Value();
    112       PrintStateId(s);
    113       *ostrm_ << FLAGS_fst_field_separator[0];
    114       PrintStateId(arc.nextstate);
    115       *ostrm_ << FLAGS_fst_field_separator[0];
    116       PrintILabel(arc.ilabel);
    117       if (!accep_) {
    118         *ostrm_ << FLAGS_fst_field_separator[0];
    119         PrintOLabel(arc.olabel);
    120       }
    121       if (show_weight_one_ || arc.weight != Weight::One())
    122         *ostrm_ << FLAGS_fst_field_separator[0] << arc.weight;
    123       *ostrm_ << "\n";
    124       output = true;
    125     }
    126     Weight final = fst_.Final(s);
    127     if (final != Weight::Zero() || !output) {
    128       PrintStateId(s);
    129       if (show_weight_one_ || final != Weight::One()) {
    130         *ostrm_ << FLAGS_fst_field_separator[0] << final;
    131       }
    132       *ostrm_ << "\n";
    133     }
    134   }
    135 
    136   const Fst<A> &fst_;
    137   const SymbolTable *isyms_;     // ilabel symbol table
    138   const SymbolTable *osyms_;     // olabel symbol table
    139   const SymbolTable *ssyms_;     // slabel symbol table
    140   bool accep_;                   // print as acceptor when possible
    141   ostream *ostrm_;               // text FST destination
    142   string dest_;                  // text FST destination name
    143   bool show_weight_one_;         // print weights equal to Weight::One()
    144   DISALLOW_COPY_AND_ASSIGN(FstPrinter);
    145 };
    146 
    147 }  // namespace fst
    148 
    149 #endif  // FST_SCRIPT_PRINT_IMPL_H_
    150