#include <parser.hpp>
Public Member Functions | |
Parser (bool translate=true) | |
~Parser () | |
const Lisp * | parse (const std::string &filename) |
Parses a lispfile and returns the s-expression structure. | |
const Lisp * | parse (std::istream &stream, const std::string &sourcename) |
Same as parse but reads from a generic std::istream. | |
Private Member Functions | |
void | parse_error (const char *msg) const __attribute__((__noreturn__)) |
const Lisp * | read () |
Parser (const Parser &) | |
Parser & | operator= (const Parser &) |
Private Attributes | |
Lexer * | lexer |
std::string | filename |
tinygettext::DictionaryManager * | dictionary_manager |
tinygettext::Dictionary * | dictionary |
Lexer::TokenType | token |
obstack | obst |
Definition at line 34 of file parser.hpp.
lisp::Parser::Parser | ( | bool | translate = true |
) |
Definition at line 33 of file parser.cpp.
References dictionary_manager, g_config, Config::locale, and obst.
00033 : 00034 lexer(0), 00035 filename(), 00036 dictionary_manager(0), 00037 dictionary(0), 00038 token(), 00039 obst() 00040 { 00041 if(translate) { 00042 dictionary_manager = new tinygettext::DictionaryManager(); 00043 dictionary_manager->set_charset("UTF-8"); 00044 if (g_config && (g_config->locale != "")) 00045 dictionary_manager->set_language(tinygettext::Language::from_name(g_config->locale)); 00046 } 00047 00048 obstack_init(&obst); 00049 }
lisp::Parser::~Parser | ( | ) |
Definition at line 51 of file parser.cpp.
References dictionary_manager, lexer, and obst.
00052 { 00053 obstack_free(&obst, NULL); 00054 delete lexer; 00055 delete dictionary_manager; 00056 }
lisp::Parser::Parser | ( | const Parser & | ) | [private] |
const Lisp * lisp::Parser::parse | ( | const std::string & | filename | ) |
Parses a lispfile and returns the s-expression structure.
Note that all memory is held by the parser so don't destroy the parser before you are finished with the lisp tree
Definition at line 68 of file parser.cpp.
References dictionary, dictionary_manager, and lisp::dirname().
Referenced by AddonManager::check_online(), ObjectFactory::create(), TitleScreen::get_level_name(), worldmap::WorldMap::get_level_title(), worldmap::WorldMap::load(), World::load(), Config::load(), SpriteManager::load(), Level::load(), CameraConfig::load(), load_music_file(), World::load_state(), Font::loadFontFile(), TileSetParser::parse(), Addon::parse(), and TextScroller::TextScroller().
00069 { 00070 IFileStreambuf ins(filename); 00071 std::istream in(&ins); 00072 00073 if(!in.good()) { 00074 std::stringstream msg; 00075 msg << "Parser problem: Couldn't open file '" << filename << "'."; 00076 throw std::runtime_error(msg.str()); 00077 } 00078 00079 if(dictionary_manager) { 00080 std::string rel_dir = dirname (filename); 00081 char **searchpath = PHYSFS_getSearchPath(); 00082 for(char** i = searchpath; *i != NULL; i++) 00083 { 00084 std::string abs_dir = std::string (*i) + PHYSFS_getDirSeparator () + rel_dir; 00085 dictionary_manager->add_directory (abs_dir); 00086 } 00087 dictionary = & (dictionary_manager->get_dictionary()); 00088 } 00089 00090 return parse(in, filename); 00091 }
const Lisp * lisp::Parser::parse | ( | std::istream & | stream, | |
const std::string & | sourcename | |||
) |
Same as parse but reads from a generic std::istream.
The sourcename is used for errormessages to indicate the source of the data.
Definition at line 94 of file parser.cpp.
References lisp::Lisp::cons, filename, lisp::Lexer::getNextToken(), lexer, obst, read(), token, lisp::Lisp::TYPE_CONS, and lisp::Lisp::v.
00095 { 00096 delete lexer; 00097 lexer = new Lexer(stream); 00098 00099 this->filename = sourcename; 00100 token = lexer->getNextToken(); 00101 00102 Lisp* result = new(obst) Lisp(Lisp::TYPE_CONS); 00103 result->v.cons.car = read(); 00104 result->v.cons.cdr = 0; 00105 00106 delete lexer; 00107 lexer = 0; 00108 00109 return result; 00110 }
void lisp::Parser::parse_error | ( | const char * | msg | ) | const [private] |
Definition at line 113 of file parser.cpp.
References filename, lisp::Lexer::getLineNumber(), and lexer.
Referenced by read().
00114 { 00115 std::stringstream emsg; 00116 emsg << "Parse Error at '" << filename << "' line " << lexer->getLineNumber() 00117 << ": " << msg; 00118 throw std::runtime_error(emsg.str()); 00119 }
const Lisp * lisp::Parser::read | ( | ) | [private] |
Definition at line 122 of file parser.cpp.
References lisp::Lisp::boolean, lisp::Lisp::cons, dictionary, lisp::Lexer::getNextToken(), lisp::Lexer::getString(), lisp::Lisp::integer, lexer, obst, parse_error(), lisp::Lisp::real, lisp::Lisp::string, token, lisp::Lexer::TOKEN_CLOSE_PAREN, lisp::Lexer::TOKEN_EOF, lisp::Lexer::TOKEN_FALSE, lisp::Lexer::TOKEN_INTEGER, lisp::Lexer::TOKEN_OPEN_PAREN, lisp::Lexer::TOKEN_REAL, lisp::Lexer::TOKEN_STRING, lisp::Lexer::TOKEN_SYMBOL, lisp::Lexer::TOKEN_TRUE, lisp::Lisp::TYPE_BOOLEAN, lisp::Lisp::TYPE_CONS, lisp::Lisp::TYPE_INTEGER, lisp::Lisp::TYPE_REAL, lisp::Lisp::TYPE_STRING, lisp::Lisp::TYPE_SYMBOL, and lisp::Lisp::v.
Referenced by parse().
00123 { 00124 Lisp* result; 00125 switch(token) { 00126 case Lexer::TOKEN_EOF: { 00127 parse_error("Unexpected EOF."); 00128 } 00129 case Lexer::TOKEN_CLOSE_PAREN: { 00130 parse_error("Unexpected ')'."); 00131 } 00132 case Lexer::TOKEN_OPEN_PAREN: { 00133 result = new(obst) Lisp(Lisp::TYPE_CONS); 00134 00135 token = lexer->getNextToken(); 00136 if(token == Lexer::TOKEN_CLOSE_PAREN) { 00137 result->v.cons.car = 0; 00138 result->v.cons.cdr = 0; 00139 break; 00140 } 00141 00142 if(token == Lexer::TOKEN_SYMBOL && 00143 strcmp(lexer->getString(), "_") == 0) { 00144 // evaluate translation function (_ str) in place here 00145 token = lexer->getNextToken(); 00146 if(token != Lexer::TOKEN_STRING) 00147 parse_error("Expected string after '(_'"); 00148 00149 result = new(obst) Lisp(Lisp::TYPE_STRING); 00150 if(dictionary) { 00151 std::string translation = dictionary->translate(lexer->getString()); 00152 result->v.string = new(obst) char[translation.size()+1]; 00153 memcpy(result->v.string, translation.c_str(), translation.size()+1); 00154 } else { 00155 size_t len = strlen(lexer->getString()) + 1; 00156 result->v.string = new(obst) char[len]; 00157 memcpy(result->v.string, lexer->getString(), len); 00158 } 00159 token = lexer->getNextToken(); 00160 if(token != Lexer::TOKEN_CLOSE_PAREN) 00161 parse_error("Expected ')' after '(_ string'"); 00162 break; 00163 } 00164 00165 Lisp* cur = result; 00166 do { 00167 cur->v.cons.car = read(); 00168 if(token == Lexer::TOKEN_CLOSE_PAREN) { 00169 cur->v.cons.cdr = 0; 00170 break; 00171 } 00172 Lisp *newcur = new(obst) Lisp(Lisp::TYPE_CONS); 00173 cur->v.cons.cdr = newcur; 00174 cur = newcur; 00175 } while(1); 00176 00177 break; 00178 } 00179 case Lexer::TOKEN_SYMBOL: { 00180 result = new(obst) Lisp(Lisp::TYPE_SYMBOL); 00181 size_t len = strlen(lexer->getString()) + 1; 00182 result->v.string = new(obst) char[len]; 00183 memcpy(result->v.string, lexer->getString(), len); 00184 break; 00185 } 00186 case Lexer::TOKEN_STRING: { 00187 result = new(obst) Lisp(Lisp::TYPE_STRING); 00188 size_t len = strlen(lexer->getString()) + 1; 00189 result->v.string = new(obst) char[len]; 00190 memcpy(result->v.string, lexer->getString(), len); 00191 break; 00192 } 00193 case Lexer::TOKEN_INTEGER: 00194 result = new(obst) Lisp(Lisp::TYPE_INTEGER); 00195 sscanf(lexer->getString(), "%d", &result->v.integer); 00196 break; 00197 case Lexer::TOKEN_REAL: 00198 result = new(obst) Lisp(Lisp::TYPE_REAL); 00199 sscanf(lexer->getString(), "%f", &result->v.real); 00200 break; 00201 case Lexer::TOKEN_TRUE: 00202 result = new(obst) Lisp(Lisp::TYPE_BOOLEAN); 00203 result->v.boolean = true; 00204 break; 00205 case Lexer::TOKEN_FALSE: 00206 result = new(obst) Lisp(Lisp::TYPE_BOOLEAN); 00207 result->v.boolean = false; 00208 break; 00209 00210 default: 00211 // this should never happen 00212 result = NULL; 00213 assert(false); 00214 } 00215 00216 token = lexer->getNextToken(); 00217 return result; 00218 }
Lexer* lisp::Parser::lexer [private] |
Definition at line 58 of file parser.hpp.
Referenced by parse(), parse_error(), read(), and ~Parser().
std::string lisp::Parser::filename [private] |
tinygettext::DictionaryManager* lisp::Parser::dictionary_manager [private] |
tinygettext::Dictionary* lisp::Parser::dictionary [private] |
Lexer::TokenType lisp::Parser::token [private] |
struct obstack lisp::Parser::obst [private] |