X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=parser.cpp;h=f63907937f80f021231c486c2628608050aea529;hb=9b8a57b8fb718491dac9a0cf70eb33b77fd9f95c;hp=e9fff01e2f2579542685d6557d020c82b2a4cb7b;hpb=c3e6657867421167e97944e6d87379853c772cb2;p=simplecms%2Futakata.git diff --git a/parser.cpp b/parser.cpp index e9fff01..f639079 100755 --- a/parser.cpp +++ b/parser.cpp @@ -72,12 +72,20 @@ smart_ptr parser::Parser::parse(smart_ptr& s { HandlerData data(gc); data.status.push(PS_INIT); - - while(true) { + + while(!data.status.empty()) { if(data.status.top() != PS_ERROR) { - data.lexm = lexer_->lex(strm); + if (data.chain) + { + data.chain = false; + } + else + { + data.lexm = lexer_->lex(strm); + } + if(data.lexm.isNull() || data.lexm->getID() == lexeme::LexemeID::eos) { @@ -94,7 +102,6 @@ smart_ptr parser::Parser::parse(smart_ptr& s } // stackのtopにはmainが殘ったままなので、data.stackのtopを追加してやる。 - smart_ptr ret(new data::Object(data.stack.top())); return ret; } @@ -172,8 +179,6 @@ bool InitHandler::exec_(HandlerData& data) { // 開き括弧である場合、compoundsに新しくpushして返る。 data.compounds.push(std::vector()); -// data.stack.push(data::Object(false, -// data.gc.add(util::makeCons()))); data.status.push(PS_LIST); } else if(data.lexm->getID() == lexeme::LexemeID::string || @@ -183,9 +188,17 @@ bool InitHandler::exec_(HandlerData& data) data.lexm->getID() == lexeme::LexemeID::boolean) { // それぞれの場合、単純にstackに各オブジェクトをpushする。 - data.stack.push( - data::Object(false, - data.gc.add(makePrimitiveFromLexeme(data.lexm)))); + + data::Object o = data::Object(false, + data.gc.add(makePrimitiveFromLexeme(data.lexm))); + if (data.compounds.empty()) + { + data.stack.push(o); + } + else + { + data.compounds.top().push_back(o); + } } else if(isAbbrev(data.lexm)) { @@ -214,13 +227,10 @@ bool InitHandler::exec_(HandlerData& data) bool ListHandler::exec_(HandlerData& data) { // list の開始部分である場合。 - data.status.pop(); if(data.lexm->getID() == lexeme::LexemeID::openParenthesis) { // 更にcompoundsに追加して積む。 data.compounds.push(std::vector()); -// data.stack.push(data::Object(false, -// data.gc.add(util::makeCons()))); data.status.push(PS_LIST); } else if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis) @@ -339,11 +349,58 @@ bool DotEndHandler::exec_(HandlerData& data) data.status.pop(); if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis) { - // topに積んであるものを、topの一段下にあるConsの末尾に追加する。 - // 追加とは言っても、実際にはcdrに直接設定するため、ちょっとだけ意味が違う。 - data::Object tmp = data.stack.top(); data.stack.pop(); - data::Object obj = util::getLastCons(data.stack.top()); - data::DataCastor()(obj)->setCdr(tmp); + // stackの頂点とcompoundsのトップを取得する。 +<<<<<<< HEAD +======= + data::Object t = data.stack.top(); data.stack.pop(); +>>>>>>> 6403bdd4479dc5a3e6ca42aa2dc9b0dc4d6bf71d + std::vector v = data.compounds.top(); data.compounds.pop(); + // vectorをConsへと変換するには、次のようにして後ろからやっていく + // 方式が一番面倒がない。 + // 1. cdrをstackのtop、carをvectorの末尾であるデータとしたconsを作成する。 + // 2. vectorの次のデータをcar、前のconsをcdrとしたconsを作成する。 + // 3. 先頭まで続ける。 + +<<<<<<< HEAD +======= + // +>>>>>>> 6403bdd4479dc5a3e6ca42aa2dc9b0dc4d6bf71d + { + // 後ろから前に向かっていく。 + std::vector::reverse_iterator begin = v.rbegin(), + end = v.rend(); + // ちょっと面倒すぎるなこれ。 +<<<<<<< HEAD + // cdrにcompoundsの末尾を、carにその前を設定する。 + data::Object o = data::Object( + false, data.gc.add( + util::makeCons(begin[1], begin[0])) + ); + begin += 2; +======= + data::Object o = data::Object( + false, data.gc.add( + util::makeCons(*begin, o)) + ); + ++begin; +>>>>>>> 6403bdd4479dc5a3e6ca42aa2dc9b0dc4d6bf71d + for (; begin != end; ++begin) + { + // 順次oに再設定していく。 + o = data::Object( + false, data.gc.add( + util::makeCons(*begin, o))); + } + + if (!data.compounds.empty()) + { + data.compounds.top().push_back(o); + } + else + { + data.stack.push(o); + } + } // ここまでは、すべてDataSpace内部のDataEntityを対象に処理しているため、 // Objectで正しく受け渡しができていれば問題は発生しない。 @@ -375,9 +432,14 @@ bool AbbrevHandler::exec_(HandlerData& data) else { // まだcompoundsが存在している場合には、これを返すようにする。 + data::Object c = data::Object( + false, data.gc.add(util::makeCons( + v[1], + data::Object(false, data.gc.add(util::makeNil())) + ))); data::Object o = data::Object(false, - data.gc.add(util::makeCons(v[0], v[1]))); + data.gc.add(util::makeCons(v[0], c))); if (!data.compounds.empty()) { data.compounds.top().push_back(o); @@ -389,6 +451,7 @@ bool AbbrevHandler::exec_(HandlerData& data) } data.status.pop(); + data.chain = true; return true; }