BEAST/BSE - Better Audio System and Sound Engine  0.8.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
sfidl-parser.hh
Go to the documentation of this file.
00001  // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
00002 
00003 #ifndef _SFIDL_PARSER_H_
00004 #define _SFIDL_PARSER_H_
00005 
00006 #include <map>
00007 #include "sfidl-utils.hh"
00008 
00009 namespace Sfidl {
00010 
00011 /* we implement a get() function since operator[] is not const */
00012 template<typename Key, typename Value>
00013 class Map : public std::map<Key,Value> {
00014 private:
00015   Value default_value;
00016 
00017 public:
00018   const Value& get(const Key& k) const {
00019     typename std::map<Key,Value>::const_iterator i = this->find(k);
00020     if (i != this->end())
00021       return i->second;
00022     else
00023       return default_value;
00024   }
00025 };
00026 
00027 /*
00028  * internationalized string: can store a conventional string,
00029  * however it can also store whether the string was given in
00030  * conventional form    "foo"     (i18n = false)
00031  * on in the i18n form  _("foo")  (i18n = true)
00032  */
00033 class IString : public String {
00034 public:
00035   bool i18n;
00036 
00037   IString() : i18n (false) {
00038   }
00039 
00040   IString(const char *str) : String (str), i18n (false) {
00041   }
00042 
00043   /* produces an escaped version "foo" or _("foo") */
00044   String escaped (const String &i18n_prefix = "_") const
00045   {
00046     String result;
00047     char *x = g_strescape (c_str(), 0);
00048     if (i18n)
00049       result = i18n_prefix + "(\"" + String (x) + "\")";
00050     else
00051       result = "\"" + String(x) + "\"";
00052     g_free (x);
00053     return result;
00054   }
00055 };
00056 
00057 struct LineInfo {
00058   bool    isInclude;
00059   int     line;
00060   String  filename;
00061 
00062   // Produce a human readable location (file:line, using "stdin" where appropriate) 
00063   String location() const
00064   {
00065     String result;
00066     char *x = g_strdup_format ("%s:%d", (filename == "-") ? "stdin" : filename.c_str(), line);
00067     result = x;
00068     g_free (x);
00069     return result;
00070   }
00071 };
00072 
00073 struct Pragma {
00074   String  filename;
00075   String  text;
00076   int     line;
00077   bool    fromInclude; /* true for normal includes; false for implIncludes and the base file */
00078 
00079   bool getString (const String& key, String& value);
00080 };
00081 
00082 struct Constant {
00083   String  name;
00084   String  file;
00085   enum { tString = 1, tFloat = 2, tInt = 3, tIdent = 4 } type;
00086 
00087   String  str;
00088   float   f;
00089   int64   i;
00090 };
00091 
00092 struct Param {
00093   String  type;
00094   String  name;
00095   String  file;
00096 
00097   IString group;
00098   String  pspec;
00099   int     line;
00100   String  args;
00101 
00102   String  label; /* first argument of the param spec contructor */
00103   String  blurb; /* second argument of the param spec contructor */
00104   String  options; /* last argument of the param spec contructor */
00105   String  literal_options; /* the real option string; note that conversion might not work,
00106                                   if building the literal option string requires things like C function calls */
00107 };
00108 
00109 struct Stream {
00110   enum Type { IStream, JStream, OStream } type;
00111   String  ident;
00112   IString label;
00113   IString blurb;
00114   String  file;
00115   int     line;
00116 };
00117 
00118 struct ChoiceValue {
00119   String  name;
00120   String  file;
00121   IString label;
00122   IString blurb;
00123 
00124   int     value;
00125   int     sequentialValue;
00126   bool    neutral;
00127 };
00128 
00129 struct Choice {
00130   /*
00131    * name if the enum, "_anonymous_" for anonymous enum - of course, when
00132    * using namespaces, this can also lead to things like "Arts::_anonymous_",
00133    * which would mean an anonymous enum in the Arts namespace
00134    */
00135   String name;
00136   String file;
00137 
00138   std::vector<ChoiceValue> contents;
00139   Map<String, IString> infos;
00140 };
00141 
00142 struct Record {
00143   String name;
00144   String file;
00145 
00146   std::vector<Param> contents;
00147   Map<String, IString> infos;
00148 };
00149 
00150 struct Sequence {
00151   String  name;
00152   String  file;
00153   Param   content;
00154   Map<String, IString> infos;
00155 };
00156 
00157 struct Method {
00158   String  name;
00159   String  file;
00160 
00161   std::vector<Param> params;
00162   Param   result;
00163   Map<String, IString> infos;
00164 };
00165 
00166 struct Class {
00167   String name;
00168   String file;
00169   String inherits;
00170 
00171   std::vector<Method>   methods;
00172   std::vector<Method>   signals;
00173   std::vector<Param>    properties;
00174   std::vector<Stream>   istreams, jstreams, ostreams;
00175   Map<String, IString>  infos;
00176 };
00177 
00178 enum TypeDeclaration {
00179   tdChoice        = 1,
00180   tdRecord        = 2,
00181   tdSequence      = 3,
00182   tdClass         = 4,
00183   tdProto         = 8,
00184   tdChoiceProto   = tdChoice | tdProto,
00185   tdRecordProto   = tdRecord | tdProto,
00186   tdSequenceProto = tdSequence | tdProto,
00187   tdClassProto    = tdClass | tdProto,
00188 };
00189 
00190 enum Type {
00191   // primitive types
00192   VOID,
00193   BOOL,
00194   INT,
00195   NUM,
00196   REAL,
00197   STRING,
00198   // enums
00199   CHOICE,
00200   // blocks of byte/float
00201   BBLOCK,
00202   FBLOCK,
00203   // generic record type:
00204   SFIREC,
00205   // user defined types
00206   SEQUENCE,
00207   RECORD,
00208   OBJECT,     /* PROXY */
00209 };
00210 
00211 class Symbol {
00212 public:
00213   String name;
00214 
00215   Symbol *parent;
00216   std::vector<Symbol *> children;
00217 
00218   Symbol();
00219   virtual ~Symbol();
00220 
00221   String   fullName ();
00222   Symbol  *find (const String& name);
00223   bool     insert (Symbol *symbol);
00224 };
00225 
00226 class Namespace : public Symbol {
00227 public:
00228   std::vector<Namespace *> used; /* from "using namespace Foo;" statements */
00229 };
00230 
00231 class Parser {
00232 protected:
00233   const class Options&      options;
00234 
00235   GScanner                 *scanner;
00236   std::vector<char>         scannerInputData;
00237   std::vector<LineInfo>     scannerLineInfo;
00238 
00239   Namespace                 rootNamespace;
00240   Namespace                *currentNamespace;
00241 
00242   std::vector<String>       includedNames;
00243   std::vector<String>       types;
00244   std::map<String,int>      typeMap;
00245 
00246   std::vector<String>       includes;          // files to include
00247   std::vector<Pragma>       pragmas;
00248   std::vector<Constant>     constants;
00249   std::vector<Choice>       choices;
00250   std::vector<Sequence>     sequences;
00251   std::vector<Record>       records;
00252   std::vector<Class>        classes;
00253   std::vector<Method>       procedures;
00254 
00255   // namespace related functions
00256 
00257   String defineSymbol (const String& name);
00258   Symbol *qualifyHelper (const String& name);
00259   String qualifySymbol (const String& name);
00260   bool enterNamespace (const String& name);
00261   void leaveNamespace ();
00262   bool usingNamespace (const String& name);
00263 
00264   // scanner related functions
00265 
00266   static void scannerMsgHandler (GScanner *scanner, gchar *message, gboolean is_error);
00267 
00268   template<class... Args> void print_error (const char *format, const Args &...args)
00269   {
00270     if (scanner->parse_errors < scanner->max_parse_errors)
00271       g_scanner_error (scanner, "%s", string_format (format, args...).c_str());
00272   }
00273   template<class... Args> void print_warning (const char *format, const Args &...args)
00274   {
00275     g_scanner_warn (scanner, "%s", string_format (format, args...).c_str());
00276   }
00277 
00278   // preprocessor
00279 
00280   void preprocess (const String& filename, bool includeImpl = false);
00281   void preprocessContents (const String& filename);
00282   bool haveIncluded (const String& filename) const;
00283   bool insideInclude () const;
00284 
00285   // parser
00286 
00287   void addConstantTodo (const Constant& cdef);
00288   void addChoiceTodo (const Choice& cdef);
00289   void addRecordTodo (const Record& rdef);
00290   void addSequenceTodo (const Sequence& sdef);
00291   void addClassTodo (const Class& cdef);
00292   void addProcedureTodo (const Method& pdef);
00293 
00294   void addPrototype (const String& type, TypeDeclaration typeDecl);
00295   void addType (const String& type, TypeDeclaration typeDecl);
00296 
00297   GTokenType parseTypeName (String& s);
00298   GTokenType parseStringOrConst (String &s);
00299   GTokenType parseConstant (bool isident = false);
00300   GTokenType parseNamespace ();
00301   GTokenType parseChoice ();
00302   GTokenType parseChoiceValue (ChoiceValue& comp, int& value, int& sequentialValue);
00303   GTokenType parseRecord ();
00304   GTokenType parseRecordField (Param& comp, const IString& group);
00305   GTokenType parseStream (Stream& stream, Stream::Type);
00306   GTokenType parseSequence ();
00307   GTokenType parseParamHints (Param &def);
00308   GTokenType parseClass ();
00309   GTokenType parseMethod (Method& def);
00310   GTokenType parseInfoOptional (Map<String,IString>& infos);
00311 public:
00312   Parser ();
00313 
00314   bool parse (const String& fileName);
00315 
00316   String fileName() const                                 { return scanner->input_name; }
00317   const std::vector<String>& getIncludes () const         { return includes; }
00318   const std::vector<Constant>& getConstants () const      { return constants; }
00319   const std::vector<Choice>& getChoices () const          { return choices; }
00320   const std::vector<Sequence>& getSequences () const      { return sequences; }
00321   const std::vector<Record>& getRecords () const          { return records; }
00322   const std::vector<Class>& getClasses () const           { return classes; }
00323   const std::vector<Method>& getProcedures () const       { return procedures; }
00324   const std::vector<String>& getTypes () const            { return types; }
00325 
00326   std::vector<Pragma> getPragmas (const String& binding) const;
00327 
00328   Sequence findSequence (const String& name) const;
00329   Record findRecord (const String& name) const;
00330   const Class* findClass (const String &name) const;
00331 
00332   bool isChoice (const String& type) const;
00333   bool isSequence (const String& type) const;
00334   bool isRecord (const String& type) const;
00335   bool isClass (const String& type) const;
00336   Type typeOf (const String& type) const;
00337   bool fromInclude (const String& type) const;
00338 };
00339 
00340 }
00341 #endif /* _SFIDL_PARSER_H_ */
00342 
00343 /* vim:set ts=8 sts=2 sw=2: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines