BEAST/BSE - Better Audio System and Sound Engine
0.8.2
|
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: */