lisp::Parser Class Reference

#include <parser.hpp>

List of all members.

Public Member Functions

 Parser (bool translate=true)
 ~Parser ()
const Lispparse (const std::string &filename)
 Parses a lispfile and returns the s-expression structure.
const Lispparse (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 Lispread ()
 Parser (const Parser &)
Parseroperator= (const Parser &)

Private Attributes

Lexerlexer
std::string filename
tinygettext::DictionaryManager * dictionary_manager
tinygettext::Dictionary * dictionary
Lexer::TokenType token
obstack obst


Detailed Description

Definition at line 34 of file parser.hpp.


Constructor & Destructor Documentation

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]


Member Function Documentation

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 }

Parser& lisp::Parser::operator= ( const Parser  )  [private]


Member Data Documentation

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]

Definition at line 59 of file parser.hpp.

Referenced by parse(), and parse_error().

tinygettext::DictionaryManager* lisp::Parser::dictionary_manager [private]

Definition at line 60 of file parser.hpp.

Referenced by parse(), Parser(), and ~Parser().

tinygettext::Dictionary* lisp::Parser::dictionary [private]

Definition at line 61 of file parser.hpp.

Referenced by parse(), and read().

Lexer::TokenType lisp::Parser::token [private]

Definition at line 62 of file parser.hpp.

Referenced by parse(), and read().

struct obstack lisp::Parser::obst [private]

Definition at line 64 of file parser.hpp.

Referenced by parse(), Parser(), read(), and ~Parser().


The documentation for this class was generated from the following files:
Generated on Mon Apr 14 03:38:48 2014 for SuperTux by  doxygen 1.5.1