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.eof() || in.fail())
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
00060 if(in.eof() || in.fail())
00061 return next;
00062
00063 in.get(c);
00064 } while(!isspace(c) && c!= comment && c != open && c != close);
00065
00066 in.putback(c);
00067
00068 return next;
00069 }
00070
00071 void Parser::consumeWhitespaceAndComments(std::istream& in)
00072 {
00073
00074 char c;
00075
00076 in.get(c);
00077 while(isspace(c) || c == comment) {
00078 if(in.eof() || in.fail())
00079 break;
00080 if(c == '\n')
00081 _lineNumber ++;
00082 if(c == comment) {
00083 while(c != '\n') {
00084 if(in.eof())
00085 break;
00086 in.get(c);
00087 }
00088 _lineNumber++;
00089 }
00090 in.get(c);
00091 }
00092
00093 in.putback(c);
00094 }
00095
00096 std::string Parser::wordWrap(std::string &strText, int chars)
00097 {
00098 stringstream text(strText + ")");
00099 stringstream line;
00100
00101 string next = getNext(text);
00102
00103 if(next != "" || !text.eof()) {
00104 do {
00105 line << next;
00106 next = " " + getNext(text);
00107 }
00108 while(line.str().size() + next.size() < chars && next != " )" && text.str() != "");
00109 }
00110
00111 if(line.str().size() == strText.size())
00112 strText = "";
00113 else
00114 strText = strText.substr(line.str().size()+1,strText.size() - line.str().size());
00115
00116 return line.str();
00117 }
00118
00119 std::string Parser::readString(std::istream& in)
00120 {
00121 string next;
00122 char c;
00123 in.get(c);
00124 while(c != '"') {
00125 next += c;
00126 in.get(c);
00127 }
00128
00129 return next;
00130 }