簡體   English   中英

編譯 FreeLing (C++) 的第一個示例代碼時出錯

[英]Error compiling the first example code of FreeLing (C++)

我已經在“Linux Mint 20.3 Cinnamon”上安裝了“freeling-4.2-focal-amd64.deb”以及此處提到的所有依賴項: https://freeling-user-manual.readthedocs.io/en/v4.2/安裝/requirements-linux/#install-dependencies

我試圖從這里編譯第一個示例代碼:

說明: https://freeling-tutorial.readthedocs.io/en/latest/example01/

代碼: https://freeling-tutorial.readthedocs.io/en/latest/code/example01.cc/

編譯時出現以下錯誤消息:

FAILED: CMakeFiles/test_freeling.dir/main.cpp.o 
/usr/bin/c++   -g -std=gnu++14 -MD -MT CMakeFiles/test_freeling.dir/main.cpp.o -MF CMakeFiles/test_freeling.dir/main.cpp.o.d -o CMakeFiles/test_freeling.dir/main.cpp.o -c /home/ben/Schreibtisch/Bachelor_Projekt/test_freeling/main.cpp
In file included from /usr/include/freeling/morfo/idioma.h:45,
                 from /usr/include/freeling/morfo/lang_ident.h:44,
                 from /usr/include/freeling.h:35,
                 from /home/ben/desktop/Projekt/test_freeling/main.cpp:2:
/usr/include/freeling/morfo/smoothingLD.h: In constructor ‘freeling::smoothingLD<G, E>::smoothingLD(const wstring&, const std::map<std::__cxx11::basic_string<wchar_t>, E>&)’:
/usr/include/freeling/morfo/smoothingLD.h:129:73: error: there are no arguments to ‘log’ that depend on a template parameter, so a declaration of ‘log’ must be available [-fpermissive]
  129 |           if (name==L"LinearDiscountAlpha") { double a; sin>>a; alpha = log(a); notalpha=log(1-a); }
      |                                                                         ^~~
/usr/include/freeling/morfo/smoothingLD.h:129:73: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/usr/include/freeling/morfo/smoothingLD.h:129:90: error: there are no arguments to ‘log’ that depend on a template parameter, so a declaration of ‘log’ must be available [-fpermissive]
  129 |           if (name==L"LinearDiscountAlpha") { double a; sin>>a; alpha = log(a); notalpha=log(1-a); }
      |                                                                                          ^~~
/usr/include/freeling/morfo/smoothingLD.h:179:18: error: there are no arguments to ‘log’ that depend on a template parameter, so a declaration of ‘log’ must be available [-fpermissive]
  179 |       pUnseen = -log(vsize-ntypes); // log version of 1/(vsize-ntypes)
      |                  ^~~
/usr/include/freeling/morfo/smoothingLD.h:180:14: error: there are no arguments to ‘log’ that depend on a template parameter, so a declaration of ‘log’ must be available [-fpermissive]
  180 |       nobs = log(nobs);
      |              ^~~

下面是對應的源代碼:

////////////////////////////////////////////////////////////////
//
//    FreeLing - Open Source Language Analyzers
//
//    Copyright (C) 2014   TALP Research Center
//                         Universitat Politecnica de Catalunya
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Affero General Public
//    License as published by the Free Software Foundation; either
//    version 3 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Affero General Public License for more details.
//
//    You should have received a copy of the GNU Affero General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//    contact: Lluis Padro (padro@lsi.upc.es)
//             TALP Research Center
//             despatx C6.212 - Campus Nord UPC
//             08034 Barcelona.  SPAIN
//
////////////////////////////////////////////////////////////////

#ifndef _SMOOTHING_LD
#define _SMOOTHING_LD

#include "freeling/morfo/traces.h"
#include "freeling/morfo/util.h"
#include "freeling/morfo/configfile.h"

#undef MOD_TRACENAME
#define MOD_TRACENAME L"SMOOTHING"
#undef MOD_TRACEMODULE
#define MOD_TRACEMODULE LANGIDENT_TRACE

namespace freeling {
  
  ///////////////////////////////////////////////////////////////
  /// Class smoothingLD computes linear-discount smoothed conditional 
  /// probabilities P(z|w1...wn) for n-gram transitions.
  /// 
  /// template parameters:
  ///   - E is the type of the ngram elements (e.g. char, int, string, etc.)
  ///   - G is the type containing the ngram (e.g. string, list<int>, vector<string>, etc.)
  ///     Elements of G must be of type E. 
  ///     G must have operations push_back(E), erase(G::iterator), and begin()
  ///////////////////////////////////////////////////////////////

  template <class G,class E> 
  class smoothingLD {
    
  private:
    /// log alpha and 1-alpha parameter for linear discount 
    double alpha; 
    double notalpha;
    /// map to store ngram counts (for any size of ngram)
    std::map<G,double> counts;
    
    // probability of unseen unigrams
    double pUnseen;
    // total number of observations
    double nobs; 

    /// order of the n-gram model. Order=3 => trigram model P(z|xy)
    size_t order;

    /// translation table for escaped symbols in input (e.g. \s, \n, \t...)
    std::map<std::wstring,E> escapes;
    
    //////////////////////////////////////////
    // Get observed counts for given ngram
    
    double count(const G &ngram) const {
      typename std::map<G, double>::const_iterator p = counts.find(ngram);
      if (p!=counts.end()) return p->second;
      else return -1;
    }
    
        
  public:
    
    //////////////////////////////////////////
    /// Constructor, load data from config file
    
    smoothingLD(const std::wstring &cfgFile, 
                const std::map<std::wstring,E> &esc=std::map<std::wstring,E>()) : escapes(esc) { 
        
      double ntypes=0; 
      double vsize=0;
      nobs=0; 
      order=0;
      
      enum sections {ORDER,NGRAMS,SMOOTHING};
      config_file cfg(true);  
      cfg.add_section(L"Order",ORDER,true);
      cfg.add_section(L"NGrams",NGRAMS,true);
      cfg.add_section(L"Smoothing",SMOOTHING,true);
      
      if (not cfg.open(cfgFile))
        ERROR_CRASH(L"Error opening file "+cfgFile);
      
      std::wstring line; 
      while (cfg.get_content_line(line)) {
        
        std::wistringstream sin;
        sin.str(line);
        
        // process each content line according to the section where it is found
        switch (cfg.get_section()) {
          
        case ORDER: {// read order of ngram model
          std::wistringstream sin;
          sin.str(line);
          size_t x; sin>>x;
          if (order!=0 and order!=x)
            ERROR_CRASH(L"ERROR - Specified model order does not match ngram size");
          order = x;
          break;
        }

        case SMOOTHING: { // reading general parameters
          std::wstring name;
          sin>>name;
          if (name==L"LinearDiscountAlpha") { double a; sin>>a; alpha = log(a); notalpha=log(1-a); }
          else if (name==L"VocabularySize") sin>>vsize;
          else ERROR_CRASH(L"Unexpected smoothing option '"+name+L"'");
          break;
        }
          
        case NGRAMS: {  // reading ngram counts
          // read counts for this ngram to table
          double c; sin >> c;
          // read ngram components into a G object.
          G ngram;
          std::wstring w; 
          while (sin >> w) {
            typename std::map<std::wstring,E>::const_iterator p=escapes.find(w);
            if (p!=escapes.end())                
              ngram.push_back(p->second);
            else
              ngram.push_back(util::wstring_to<E>(w));
          }

          if (order==0) order = ngram.size();
          else if (order != ngram.size()) 
            ERROR_CRASH(L"ERROR - Mixed order ngrams in input file, or specified model order does not match ngram size");

          // add ngram (and n-i gram) counts to the model
          while (ngram.size()>1) {
            // insert ngram count, or increase if it already existed
            std::pair<typename std::map<G,double>::iterator,bool> x = counts.insert(make_pair(ngram,c));
            if (not x.second) x.first->second += c;            
            // shorten n gram and loop to insert n-1 gram
            ngram.erase(std::prev(ngram.end()));
          }
          // unigram is left. Add it
          std::pair<typename std::map<G,double>::iterator,bool> x = counts.insert(make_pair(ngram,c));
          if (x.second) ntypes++; // new unigram inserted, increase type count
          else x.first->second += c;  // existing unigram, increase count

          // update total observation counts
          nobs += c;
          break;
        }
          
        default: break;
        }
      }
      cfg.close();       

      // precompute logs needed for logprob
      if (vsize<=ntypes)
        ERROR_CRASH(L"VocabularySize can not be smaller than number of different observed unigrams.");
      pUnseen = -log(vsize-ntypes); // log version of 1/(vsize-ntypes)
      nobs = log(nobs);
      for (typename std::map<G,double>::iterator c=counts.begin(); c!=counts.end(); c++) 
        c->second = log(c->second); 
    }
    
    //////////////////////////////////////////
    /// destructor
    
    ~smoothingLD() {}
         
    //////////////////////////////////////////
    /// Compute smoothed conditional log prob of seeing 
    /// symbol z following given ngram P(z|ngram)
    
    double Prob(const G &ngram, const E &z) const {
      
      // seq =  n+1 gram ( ngram + z )
      G seq = ngram; 
      seq.push_back(z);
      // log count of complete ngram
      double c = count(seq);

      if (ngram.size()==0) {
        // no conditioning history, use unigrams (seq = [z])
        if (c>=0) return notalpha + c - nobs;  // log version of (1-alpha)*count(c)/nobs
        else return alpha + pUnseen;   // log version of alpha * punseen
      }
      
      else {
        // conditioning history, use LD smoothing
        if (c>=0) return notalpha + c - count(ngram); // log version of (1-alpha)*count(c)/count(ngram)
        else {
          // shorten history and recurse
          G sht = ngram; sht.erase(sht.begin());
          return alpha + Prob(sht,z);  // log version of alpha * Prob(sht,z)
        }
      }
    }
  };
  
} // namespace

#undef MOD_TRACENAME
#undef MOD_TRACECODE

#endif

為什么在 lib 的這個文件中無法識別日志,我該怎么辦?

似乎該庫沒有包含正確的 header 文件( <cmath> ),並且它使用std::log就好像它保證可以用作log一樣。

我建議您嘗試讓FreeLing的提供者更新庫,並在等待他們解決問題時,您可以嘗試這樣做:

#include <cmath>
using std::log;

在您自己的代碼中包含任何 FreeLing 標頭之前

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM