00001 #include <iostream> 00002 #include <sstream> 00003 00004 #include "Parser.h" 00005 00006 using namespace std; 00007 int Parser::_lineNumber = 0; 00008 char Parser::comment = ';'; 00009 char Parser::open = '('; 00010 char Parser::close = ')'; 00011 00012 List *Parser::parse(std::string filename) 00013 { 00014 ifstream in(filename.c_str()); 00015 return parse(in); 00016 } 00017 00018 List *Parser::parse(std::istream& in) 00019 { 00020 _lineNumber = 0; 00021 getNext(in); 00022 return parseOpen(in); 00023 } 00024 00025 List *Parser::parseOpen(std::istream &in) 00026 { 00027 List *newList = new List(_lineNumber); 00028 string next = getNext(in); 00029 while(next[0] != close) { 00030 if(next[0] == open) 00031 newList->snoc(parseOpen(in)); 00032 else 00033 newList->snoc(new Atom(string(next),_lineNumber)); 00034 next = getNext(in); 00035 } 00036 return newList; 00037 } 00038 00039 std::string Parser::getNext(std::istream& in) 00040 { 00041 consumeWhitespaceAndComments(in); 00042 00043 if(!in) 00044 return ""; 00045 00046 string next; 00047 char c; 00048 00049 in.get(c); 00050 do { 00051 if(c == '"') 00052 return readString(in); 00053 00054 next += c; 00055 if(c == open || c == close) { 00056 in.get(c); 00057 break; 00058 } 00059 in.get(c); 00060 } while(!isspace(c) && c!= comment && c != open && c != close); 00061 in.putback(c); 00062 00063 return next; 00064 } 00065 00066 void Parser::consumeWhitespaceAndComments(std::istream& in) 00067 { 00068 char c; 00069 in.get(c); 00070 while(isspace(c) || c == comment) { 00071 if(!in) 00072 break; 00073 if(c == '\n') 00074 _lineNumber ++; 00075 if(c == comment) { 00076 while(c != '\n') { 00077 if(!in) 00078 break; 00079 in.get(c); 00080 } 00081 _lineNumber++; 00082 } 00083 in.get(c); 00084 } 00085 00086 in.putback(c); 00087 } 00088 00089 std::string Parser::readString(std::istream& in) 00090 { 00091 string next; 00092 char c; 00093 in.get(c); 00094 while(c != '"') { 00095 next += c; 00096 in.get(c); 00097 } 00098 00099 return next; 00100 }