OSDN Git Service

parserの内部をハンドラ化。PARSERSTATUSがparser_handlerにて必要になった
authorderui <derutakayu@user.sourceforge.jp>
Wed, 19 Aug 2009 13:05:02 +0000 (22:05 +0900)
committerderui <derutakayu@user.sourceforge.jp>
Wed, 19 Aug 2009 13:05:02 +0000 (22:05 +0900)
ため、parser_status.hに分離。

Makefile
config.log
config.status
parser.cpp
parser.h
parser_handler.cpp
parser_handler.h
parser_status.h [new file with mode: 0755]
test/Makefile
tree.cpp

index ab82351..8f4beed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -86,11 +86,11 @@ DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 distuninstallcheck_listfiles = find . -type f -print
 distcleancheck_listfiles = find . -type f -print
-ACLOCAL = ${SHELL} /home/derui/develop/utakata/missing --run aclocal-1.10
-AMTAR = ${SHELL} /home/derui/develop/utakata/missing --run tar
-AUTOCONF = ${SHELL} /home/derui/develop/utakata/missing --run autoconf
-AUTOHEADER = ${SHELL} /home/derui/develop/utakata/missing --run autoheader
-AUTOMAKE = ${SHELL} /home/derui/develop/utakata/missing --run automake-1.10
+ACLOCAL = ${SHELL} /home/derui/develop/sdl/missing --run aclocal-1.10
+AMTAR = ${SHELL} /home/derui/develop/sdl/missing --run tar
+AUTOCONF = ${SHELL} /home/derui/develop/sdl/missing --run autoconf
+AUTOHEADER = ${SHELL} /home/derui/develop/sdl/missing --run autoheader
+AUTOMAKE = ${SHELL} /home/derui/develop/sdl/missing --run automake-1.10
 AWK = gawk
 CC = gcc
 CCDEPMODE = depmode=gcc3
@@ -118,7 +118,7 @@ LDFLAGS =
 LIBOBJS = 
 LIBS = 
 LTLIBOBJS = 
-MAKEINFO = ${SHELL} /home/derui/develop/utakata/missing --run makeinfo
+MAKEINFO = ${SHELL} /home/derui/develop/sdl/missing --run makeinfo
 MKDIR_P = /bin/mkdir -p
 OBJEXT = o
 PACKAGE = utakata
@@ -132,10 +132,10 @@ SET_MAKE =
 SHELL = /bin/sh
 STRIP = 
 VERSION = 0.0.1
-abs_builddir = /home/derui/develop/utakata
-abs_srcdir = /home/derui/develop/utakata
-abs_top_builddir = /home/derui/develop/utakata
-abs_top_srcdir = /home/derui/develop/utakata
+abs_builddir = /home/derui/develop/sdl
+abs_srcdir = /home/derui/develop/sdl
+abs_top_builddir = /home/derui/develop/sdl
+abs_top_srcdir = /home/derui/develop/sdl
 ac_ct_CC = gcc
 ac_ct_CXX = g++
 am__include = include
@@ -155,7 +155,7 @@ host_alias =
 htmldir = ${docdir}
 includedir = ${prefix}/include
 infodir = ${datarootdir}/info
-install_sh = $(SHELL) /home/derui/develop/utakata/install-sh
+install_sh = $(SHELL) /home/derui/develop/sdl/install-sh
 libdir = ${exec_prefix}/lib
 libexecdir = ${exec_prefix}/libexec
 localedir = ${datarootdir}/locale
index 6909e27..1847532 100644 (file)
@@ -12,11 +12,11 @@ generated by GNU Autoconf 2.63.  Invocation command line was
 
 hostname = localhost
 uname -m = i686
-uname -r = 2.6.30-gentoo-r4
+uname -r = 2.6.29-gentoo-r5
 uname -s = Linux
-uname -v = #1 SMP Wed Aug 5 22:37:26 JST 2009
+uname -v = #8 SMP Sun Jul 5 03:55:20 JST 2009
 
-/usr/bin/uname -p = Intel(R) Core(TM)2 Duo CPU P8800 @ 2.66GHz
+/usr/bin/uname -p = Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
 /bin/uname -X     = unknown
 
 /bin/arch              = unknown
@@ -28,7 +28,6 @@ uname -v = #1 SMP Wed Aug 5 22:37:26 JST 2009
 /bin/universe          = unknown
 
 PATH: /home/derui/bin
-PATH: /usr/local/stow/bin
 PATH: /usr/local/bin
 PATH: /usr/local/sbin
 PATH: /usr/sbin
@@ -450,14 +449,14 @@ am_cv_CXX_dependencies_compiler_type=gcc3
 ## Output variables. ##
 ## ----------------- ##
 
-ACLOCAL='${SHELL} /home/derui/develop/utakata/missing --run aclocal-1.10'
+ACLOCAL='${SHELL} /home/derui/develop/sdl/missing --run aclocal-1.10'
 AMDEPBACKSLASH='\'
 AMDEP_FALSE='#'
 AMDEP_TRUE=''
-AMTAR='${SHELL} /home/derui/develop/utakata/missing --run tar'
-AUTOCONF='${SHELL} /home/derui/develop/utakata/missing --run autoconf'
-AUTOHEADER='${SHELL} /home/derui/develop/utakata/missing --run autoheader'
-AUTOMAKE='${SHELL} /home/derui/develop/utakata/missing --run automake-1.10'
+AMTAR='${SHELL} /home/derui/develop/sdl/missing --run tar'
+AUTOCONF='${SHELL} /home/derui/develop/sdl/missing --run autoconf'
+AUTOHEADER='${SHELL} /home/derui/develop/sdl/missing --run autoheader'
+AUTOMAKE='${SHELL} /home/derui/develop/sdl/missing --run automake-1.10'
 AWK='gawk'
 CC='gcc'
 CCDEPMODE='depmode=gcc3'
@@ -484,7 +483,7 @@ LDFLAGS=''
 LIBOBJS=''
 LIBS=''
 LTLIBOBJS=''
-MAKEINFO='${SHELL} /home/derui/develop/utakata/missing --run makeinfo'
+MAKEINFO='${SHELL} /home/derui/develop/sdl/missing --run makeinfo'
 MKDIR_P='/bin/mkdir -p'
 OBJEXT='o'
 PACKAGE='utakata'
@@ -521,7 +520,7 @@ host_alias=''
 htmldir='${docdir}'
 includedir='${prefix}/include'
 infodir='${datarootdir}/info'
-install_sh='$(SHELL) /home/derui/develop/utakata/install-sh'
+install_sh='$(SHELL) /home/derui/develop/sdl/install-sh'
 libdir='${exec_prefix}/lib'
 libexecdir='${exec_prefix}/libexec'
 localedir='${datarootdir}/locale'
@@ -561,129 +560,3 @@ target_alias=''
 #define HAVE_STDBOOL_H 1
 
 configure: exit 0
-
-## ---------------------- ##
-## Running config.status. ##
-## ---------------------- ##
-
-This file was extended by utakata config.status 0.0.1, which was
-generated by GNU Autoconf 2.63.  Invocation command line was
-
-  CONFIG_FILES    = 
-  CONFIG_HEADERS  = 
-  CONFIG_LINKS    = 
-  CONFIG_COMMANDS = 
-  $ ./config.status test/Makefile depfiles
-
-on localhost
-
-config.status:776: creating test/Makefile
-config.status:1050: executing depfiles commands
-
-## ---------------------- ##
-## Running config.status. ##
-## ---------------------- ##
-
-This file was extended by utakata config.status 0.0.1, which was
-generated by GNU Autoconf 2.63.  Invocation command line was
-
-  CONFIG_FILES    = 
-  CONFIG_HEADERS  = 
-  CONFIG_LINKS    = 
-  CONFIG_COMMANDS = 
-  $ ./config.status test/Makefile depfiles
-
-on localhost
-
-config.status:776: creating test/Makefile
-config.status:1050: executing depfiles commands
-
-## ---------------------- ##
-## Running config.status. ##
-## ---------------------- ##
-
-This file was extended by utakata config.status 0.0.1, which was
-generated by GNU Autoconf 2.63.  Invocation command line was
-
-  CONFIG_FILES    = 
-  CONFIG_HEADERS  = 
-  CONFIG_LINKS    = 
-  CONFIG_COMMANDS = 
-  $ ./config.status test/Makefile depfiles
-
-on localhost
-
-config.status:776: creating test/Makefile
-config.status:1050: executing depfiles commands
-
-## ---------------------- ##
-## Running config.status. ##
-## ---------------------- ##
-
-This file was extended by utakata config.status 0.0.1, which was
-generated by GNU Autoconf 2.63.  Invocation command line was
-
-  CONFIG_FILES    = 
-  CONFIG_HEADERS  = 
-  CONFIG_LINKS    = 
-  CONFIG_COMMANDS = 
-  $ ./config.status test/Makefile depfiles
-
-on localhost
-
-config.status:776: creating test/Makefile
-config.status:1050: executing depfiles commands
-
-## ---------------------- ##
-## Running config.status. ##
-## ---------------------- ##
-
-This file was extended by utakata config.status 0.0.1, which was
-generated by GNU Autoconf 2.63.  Invocation command line was
-
-  CONFIG_FILES    = 
-  CONFIG_HEADERS  = 
-  CONFIG_LINKS    = 
-  CONFIG_COMMANDS = 
-  $ ./config.status test/Makefile depfiles
-
-on localhost
-
-config.status:776: creating test/Makefile
-config.status:1050: executing depfiles commands
-
-## ---------------------- ##
-## Running config.status. ##
-## ---------------------- ##
-
-This file was extended by utakata config.status 0.0.1, which was
-generated by GNU Autoconf 2.63.  Invocation command line was
-
-  CONFIG_FILES    = 
-  CONFIG_HEADERS  = 
-  CONFIG_LINKS    = 
-  CONFIG_COMMANDS = 
-  $ ./config.status test/Makefile depfiles
-
-on localhost
-
-config.status:776: creating test/Makefile
-config.status:1050: executing depfiles commands
-
-## ---------------------- ##
-## Running config.status. ##
-## ---------------------- ##
-
-This file was extended by utakata config.status 0.0.1, which was
-generated by GNU Autoconf 2.63.  Invocation command line was
-
-  CONFIG_FILES    = 
-  CONFIG_HEADERS  = 
-  CONFIG_LINKS    = 
-  CONFIG_COMMANDS = 
-  $ ./config.status test/Makefile depfiles
-
-on localhost
-
-config.status:776: creating test/Makefile
-config.status:1050: executing depfiles commands
index 7c2c728..9e6c64c 100755 (executable)
@@ -363,7 +363,7 @@ Copyright (C) 2008 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
-ac_pwd='/home/derui/develop/utakata'
+ac_pwd='/home/derui/develop/sdl'
 srcdir='.'
 INSTALL='/usr/bin/install -c'
 MKDIR_P='/bin/mkdir -p'
@@ -562,7 +562,7 @@ S["CXXFLAGS"]="-g -O2"
 S["CXX"]="g++"
 S["am__untar"]="${AMTAR} xf -"
 S["am__tar"]="${AMTAR} chof - \"$$tardir\""
-S["AMTAR"]="${SHELL} /home/derui/develop/utakata/missing --run tar"
+S["AMTAR"]="${SHELL} /home/derui/develop/sdl/missing --run tar"
 S["am__leading_dot"]="."
 S["SET_MAKE"]=""
 S["AWK"]="gawk"
@@ -570,12 +570,12 @@ S["mkdir_p"]="/bin/mkdir -p"
 S["MKDIR_P"]="/bin/mkdir -p"
 S["INSTALL_STRIP_PROGRAM"]="$(install_sh) -c -s"
 S["STRIP"]=""
-S["install_sh"]="$(SHELL) /home/derui/develop/utakata/install-sh"
-S["MAKEINFO"]="${SHELL} /home/derui/develop/utakata/missing --run makeinfo"
-S["AUTOHEADER"]="${SHELL} /home/derui/develop/utakata/missing --run autoheader"
-S["AUTOMAKE"]="${SHELL} /home/derui/develop/utakata/missing --run automake-1.10"
-S["AUTOCONF"]="${SHELL} /home/derui/develop/utakata/missing --run autoconf"
-S["ACLOCAL"]="${SHELL} /home/derui/develop/utakata/missing --run aclocal-1.10"
+S["install_sh"]="$(SHELL) /home/derui/develop/sdl/install-sh"
+S["MAKEINFO"]="${SHELL} /home/derui/develop/sdl/missing --run makeinfo"
+S["AUTOHEADER"]="${SHELL} /home/derui/develop/sdl/missing --run autoheader"
+S["AUTOMAKE"]="${SHELL} /home/derui/develop/sdl/missing --run automake-1.10"
+S["AUTOCONF"]="${SHELL} /home/derui/develop/sdl/missing --run autoconf"
+S["ACLOCAL"]="${SHELL} /home/derui/develop/sdl/missing --run aclocal-1.10"
 S["VERSION"]="0.0.1"
 S["PACKAGE"]="utakata"
 S["CYGPATH_W"]="echo"
index a814835..72c5d47 100755 (executable)
@@ -4,6 +4,8 @@
 #include "parser.h"
 
 #include "lexeme.h"
+#include "lexer.h"
+
 #include "lexeme_id.h"
 #include "tree.h"
 #include "literal.h"
@@ -31,8 +33,29 @@ const char* parser::DatumException::what () const throw ()
 // Parser Implementations //
 ////////////////////////////
 
-parser::Parser::Parser (smart_ptr<lexer::Lexer> l) : lexer_(l)
+parser::Parser::Parser (smart_ptr<lexer::Lexer> l) : lexer_(l),
+                                                     handler_()
 {
+    // 初期状態用ハンドラの設定
+    std::pair<PARSERSTATUS, smart_ptr<IParserHandler> > p;
+    p.first = PS_INIT;
+    p.second.add(new InitHandler);
+    handler_.insert(p);
+
+    // リスト内部用ハンドラの設定
+    p.first = PS_LIST_CAR;
+    p.second.add(new ListHandler);
+    handler_.insert(p);
+
+    // .内用ハンドラの設定
+    p.first = PS_AFTER_DOT;
+    p.second.add(new DotHandler);
+    handler_.insert(p);
+
+    // abbreviation用ハンドラの設定
+    p.first = PS_ABBREVIATION;
+    p.second.add(new AbbrevHandler);
+    handler_.insert(p);
 }
 
 smart_ptr<syntax::Tree> parser::Parser::parse (smart_ptr<utf8::UTF8InputStream>& strm)
@@ -49,177 +72,8 @@ smart_ptr<syntax::Tree> parser::Parser::parse (smart_ptr<utf8::UTF8InputStream>&
             break;
         }
 
-        // lexeme が返ってきたら、構文定義に該当するかどうかを調べる。
-        // scheme の構文定義はシンプルかつ例外のないものになっているため、
-        // 各定義とするのは簡単である。
-        if (statusstack.top() == PS_INIT)
-        {
-            if (lexm->getID () == lexeme::LexemeID::openParenthesis)
-            {
-                // 開き括弧である場合
-                statusstack.push(PS_LIST_CAR);
-                stack.push(t);
-                t.add(new syntax::Tree);
-            }
-            else if (lexm->getID () == lexeme::LexemeID::string ||
-                     lexm->getID () == lexeme::LexemeID::number ||
-                     lexm->getID () == lexeme::LexemeID::identifier ||
-                     lexm->getID () == lexeme::LexemeID::charactor ||
-                     lexm->getID () == lexeme::LexemeID::boolean)
-            {
-                // それぞれの場合、 lexeme_datum として扱われる。
-                // cdrを追加して、次に進む。
-                if (syntax::hasCar(*t))
-                {
-                    t->concat(literal::generateLiteral(lexm));
-                }
-                else
-                {
-                    syntax::setLiteralToCar(*t, literal::generateLiteral(lexm));
-                }
-//                t = t->appendCdr(syntax::DatumID::list);
-                statusstack.pop();
-            }
-            else if (isAbbrev(lexm))
-            {
-                // abbreviation を判別して status を返す。
-                syntax::setLiteralToCar(*t, literal::generateLiteral(lexm),
-                                        getAbbrevID(lexm));
-                stack.push(t);
-                t.add(new syntax::Tree);
-
-                // status stackに、PS_PABBREVIATIONとPS_INITを積む。
-                statusstack.push(PS_ABBREVIATION);
-                statusstack.push(PS_INIT);
-            }
-            else
-            {
-                throw DatumException ("datum の開始記号ではありません");
-            }
-        }
-        else if (statusstack.top() == PS_LIST_CAR)
-        {
-            // listの内部である場合。
-            if (lexm->getID () == lexeme::LexemeID::openParenthesis)
-            {
-                // スタックに積む。
-                stack.push(t);
-                t.add(new syntax::Tree);
-            }
-            else if (lexm->getID () == lexeme::LexemeID::closeParenthesis)
-            {
-                // スタックから取り出す。
-                smart_ptr<syntax::Tree> tree2 = stack.top(); stack.pop();
-                // carが空かどうかでチェックする。
-                if (!syntax::hasCar(*tree2))
-                {
-                    tree2->appendTreeToCar(t);
-                    t = tree2;
-                }
-                else
-                {
-                    tree2->concat(t);
-                }
-            }
-            else if (lexm->getID () == lexeme::LexemeID::string ||
-                     lexm->getID () == lexeme::LexemeID::number ||
-                     lexm->getID () == lexeme::LexemeID::identifier ||
-                     lexm->getID () == lexeme::LexemeID::charactor ||
-                     lexm->getID () == lexeme::LexemeID::boolean)
-            {
-                // carが空かどうかをチェックして、設定を行う必要がある。
-                if (!syntax::hasCar(*t))
-                {
-                    syntax::setLiteralToCar(*t, literal::generateLiteral(lexm));
-                }
-                else
-                {
-                    t->concat(literal::generateLiteral(lexm));
-                }
-            }
-            else if (isAbbrev(lexm))
-            {
-                // abbreviation を判別して status を返す。
-                // この場合、新規にツリーを作成して、再度設定を行う。
-                std::cout << t->toValue()->toStr() << std::endl;
-                stack.push(t);
-                t.add(new syntax::Tree);
-                syntax::setLiteralToCar(*t, literal::generateLiteral(lexm),
-                                        getAbbrevID(lexm));
-                // status stackに、PS_PABBREVIATIONとPS_INITを積む。
-                statusstack.push(PS_ABBREVIATION);
-                statusstack.push(PS_INIT);
-            }
-            else if (lexm->getID() == lexeme::LexemeID::dot)
-            {
-                // .が来た場合、かつcarが設定されていない場合には、エラーとなる。
-                if (!syntax::hasCar(*t))
-                {
-                    throw DatumException ("リストの先頭に . が設定されることは出来ません");
-                }
-                statusstack.push(PS_AFTER_DOT);
-            }
-        }
-        else if (statusstack.top() == PS_AFTER_DOT)
-        {
-            // .の後である場合。
-            if (lexm->getID () == lexeme::LexemeID::openParenthesis)
-            {
-                // 開き括弧である場合
-                stack.push(t);
-                t.add(new syntax::Tree);
-                statusstack.push(PS_LIST_CAR);
-            }
-            else if (lexm->getID () == lexeme::LexemeID::string ||
-                     lexm->getID () == lexeme::LexemeID::number ||
-                     lexm->getID () == lexeme::LexemeID::identifier ||
-                     lexm->getID () == lexeme::LexemeID::charactor ||
-                     lexm->getID () == lexeme::LexemeID::boolean)
-            {
-                // リテラルの場合、単純に戻るのみとなる。
-                t->appendCdr(syntax::DatumID::literal);
-                t->cdr()->setLiteral(literal::generateLiteral(lexm));
-                statusstack.pop();
-            }
-            else if (lexm->getID() == lexeme::LexemeID::closeParenthesis)
-            {
-                smart_ptr<syntax::Tree> tree2 = stack.top(); stack.pop();
-                // carが空かどうかでチェックする。
-                if (!syntax::hasCar(*tree2))
-                {
-                    tree2->appendTreeToCar(t);
-                }
-                else
-                {
-                    tree2->concat(t);
-                }
-                t = t->cdr();
-                // 基本的にステータスはpopするのみ。
-                statusstack.pop();
-            }
-        }
-        else if (statusstack.top() == PS_ABBREVIATION)
-        {
-            // この場合には、stackのtopに現在のツリーをconcatし、その後
-            // 更にpopして追加を行う。
-            // carが空かどうかをチェックして、設定を行う必要がある。
-            smart_ptr<syntax::Tree> t2 = stack.top(); stack.pop();
-            t2->concat(t);
-
-            // この時点で、abbrev開始前のnodeに戻ることができる。
-            t = stack.top(); stack.pop();
-            if (!syntax::hasCar(*t))
-            {
-                t->appendTreeToCar(t2);
-            }
-            else
-            {
-                t->concat(t2);
-            }
-            // datumが終了したため、次はcdrが基準となる。
-            t = t2->cdr();
-            statusstack.pop();
-        }
+        // 基本的にすべてハンドラに任せる。
+        handler_[statusstack.top()]->exec(t, lexm, stack, statusstack);
     }
 
     // 終端に逹した時点で、stackにデータが殘っていたら例外。
@@ -276,3 +130,202 @@ syntax::DatumID parser::getAbbrevID(smart_ptr<lexeme::ILexeme> l)
     }
 }
 
+bool InitHandler::exec_(smart_ptr<syntax::Tree>& main,
+                       const smart_ptr<lexeme::ILexeme>& lexm,
+                       treestack& stack,
+                       std::stack<PARSERSTATUS>& status)
+{
+    // 初期状態の解釈処理を行う。
+    if (lexm->getID () == lexeme::LexemeID::openParenthesis)
+    {
+        // 開き括弧である場合
+        status.push(PS_LIST_CAR);
+        stack.push(main);
+        main.add(new syntax::Tree);
+    }
+    else if (lexm->getID () == lexeme::LexemeID::string ||
+             lexm->getID () == lexeme::LexemeID::number ||
+             lexm->getID () == lexeme::LexemeID::identifier ||
+             lexm->getID () == lexeme::LexemeID::charactor ||
+             lexm->getID () == lexeme::LexemeID::boolean)
+    {
+        // それぞれの場合、 lexeme_datum として扱われる。
+        // cdrを追加して、次に進む。
+        if (syntax::hasCar(*main))
+        {
+            main->concat(literal::generateLiteral(lexm));
+        }
+        else
+        {
+            syntax::setLiteralToCar(*main, literal::generateLiteral(lexm));
+        }
+        status.pop();
+    }
+    else if (isAbbrev(lexm))
+    {
+        // abbreviation を判別して status を返す。
+        syntax::setLiteralToCar(*main, literal::generateLiteral(lexm),
+                                getAbbrevID(lexm));
+        stack.push(main);
+        main.add(new syntax::Tree);
+
+        // status stackに、PS_PABBREVIATIONとPS_INITを積む。
+        status.push(PS_ABBREVIATION);
+        status.push(PS_INIT);
+    }
+    else
+    {
+        throw DatumException ("datum の開始記号ではありません");
+    }
+
+    return true;
+}
+
+// List内部処理のハンドリング
+
+bool ListHandler::exec_(smart_ptr<syntax::Tree>& main,
+                       const smart_ptr<lexeme::ILexeme>& lexm,
+                       treestack& stack,
+                       std::stack<PARSERSTATUS>& status)
+{
+    // listの内部である場合。
+    if (lexm->getID () == lexeme::LexemeID::openParenthesis)
+    {
+        // スタックに積む。
+        stack.push(main);
+        main.add(new syntax::Tree);
+        // 再度積む。
+        status.push(PS_LIST_CAR);
+    }
+    else if (lexm->getID () == lexeme::LexemeID::closeParenthesis)
+    {
+        // スタックから取り出す。
+        smart_ptr<syntax::Tree> tree2 = stack.top(); stack.pop();
+        // carが空かどうかでチェックする。
+        if (!syntax::hasCar(*tree2))
+        {
+            tree2->appendTreeToCar(main);
+        }
+        else
+        {
+            tree2->concat(main);
+        }
+        main = tree2;
+        // 現在のPS_LIST_CARをpopする。
+        status.pop();
+    }
+    else if (lexm->getID () == lexeme::LexemeID::string ||
+             lexm->getID () == lexeme::LexemeID::number ||
+             lexm->getID () == lexeme::LexemeID::identifier ||
+             lexm->getID () == lexeme::LexemeID::charactor ||
+             lexm->getID () == lexeme::LexemeID::boolean)
+    {
+        // carが空かどうかをチェックして、設定を行う必要がある。
+        if (!syntax::hasCar(*main))
+        {
+            syntax::setLiteralToCar(*main, literal::generateLiteral(lexm));
+        }
+        else
+        {
+            main->concat(literal::generateLiteral(lexm));
+        }
+    }
+    else if (isAbbrev(lexm))
+    {
+        // abbreviation を判別して status を返す。
+        // この場合、新規にツリーを作成して、再度設定を行う。
+        stack.push(main);
+        main.add(new syntax::Tree);
+        syntax::setLiteralToCar(*main, literal::generateLiteral(lexm),
+                                getAbbrevID(lexm));
+        // status stackに、PS_PABBREVIATIONとPS_INITを積む。
+        status.push(PS_ABBREVIATION);
+        status.push(PS_INIT);
+    }
+    else if (lexm->getID() == lexeme::LexemeID::dot)
+    {
+        // .が来た場合、かつcarが設定されていない場合には、エラーとなる。
+        if (!syntax::hasCar(*main))
+        {
+            throw DatumException ("リストの先頭に . が設定されることは出来ません");
+        }
+        status.push(PS_AFTER_DOT);
+    }
+
+    return true;
+}
+
+// dot処理内部のハンドリング
+
+bool DotHandler::exec_(smart_ptr<syntax::Tree>& main,
+                       const smart_ptr<lexeme::ILexeme>& lexm,
+                       treestack& stack,
+                       std::stack<PARSERSTATUS>& status)
+{
+    // .の後である場合。
+    if (lexm->getID () == lexeme::LexemeID::openParenthesis)
+    {
+        // 開き括弧である場合
+        stack.push(main);
+        main.add(new syntax::Tree);
+        status.push(PS_LIST_CAR);
+    }
+    else if (lexm->getID () == lexeme::LexemeID::string ||
+             lexm->getID () == lexeme::LexemeID::number ||
+             lexm->getID () == lexeme::LexemeID::identifier ||
+             lexm->getID () == lexeme::LexemeID::charactor ||
+             lexm->getID () == lexeme::LexemeID::boolean)
+    {
+        // リテラルの場合、単純に戻るのみとなる。
+        main->appendCdr(syntax::DatumID::literal);
+        main->cdr()->setLiteral(literal::generateLiteral(lexm));
+        status.pop();
+    }
+    else if (lexm->getID() == lexeme::LexemeID::closeParenthesis)
+    {
+        smart_ptr<syntax::Tree> tree2 = stack.top(); stack.pop();
+        // carが空かどうかでチェックする。
+        if (!syntax::hasCar(*tree2))
+        {
+            tree2->appendTreeToCar(main);
+        }
+        else
+        {
+            tree2->concat(main);
+        }
+        main = main->cdr();
+        // 基本的にステータスはpopするのみ。
+        status.pop();
+    }
+    return true;
+}
+
+// ABBREVIATION処理のハンドリング。
+
+bool AbbrevHandler::exec_(smart_ptr<syntax::Tree>& main,
+                          const smart_ptr<lexeme::ILexeme>& lexm,
+                          treestack& stack,
+                          std::stack<PARSERSTATUS>& status)
+{
+    // この場合には、stackのtopに現在のツリーをconcatし、その後
+    // 更にpopして追加を行う。
+    // carが空かどうかをチェックして、設定を行う必要がある。
+    smart_ptr<syntax::Tree> t2 = stack.top(); stack.pop();
+    t2->concat(main);
+
+    // この時点で、abbrev開始前のnodeに戻ることができる。
+    main = stack.top(); stack.pop();
+    if (!syntax::hasCar(*main))
+    {
+        main->appendTreeToCar(t2);
+    }
+    else
+    {
+        main->concat(t2);
+    }
+    // datumが終了したため、次はcdrが基準となる。
+    main = t2->cdr();
+    status.pop();
+
+    return true;
+}
index 836d44e..2324fcb 100755 (executable)
--- a/parser.h
+++ b/parser.h
@@ -3,19 +3,25 @@
 
 #include <string>
 #include <vector>
+#include <map>
 
-#include "lexer.h"
 #include "smart_ptr.h"
-#include "utf8.h"
+#include "parser_handler.h"
+#include "parser_status.h"
 
 namespace utakata {
 
     namespace syntax {
         class Tree;
+        class DatumID;
     };
 
-    namespace syntax {
-        class DatumID;
+    namespace lexer {
+        class Lexer;
+    };
+
+    namespace utf8 {
+        class UTF8InputStream;
     };
 
     namespace parser {
@@ -32,20 +38,6 @@ namespace utakata {
             std::string str_;
         };
 
-        enum PARSERSTATUS {
-            PS_INIT                = 0,  /* 初期時点 */
-            PS_DATUM               = 1,  /* detumであるかどうか */
-            PS_LEXEME_DATUM        = 2,  /* lexeme_detumのどれかであるか */
-            PS_LIST_CAR            = 4,  /* リストの開始 - (,[ */
-            PS_LIST_END            = 5,  /* リストの終了 - (,[と対応する),] */
-            PS_AFTER_DOT           = 6,  /* リスト中に出現した . */
-            PS_ABBREVIATION        = 7,  // abbrev syntaxの後。
-            PS_VECTOR_START        = 15, /* #( */
-            PS_VECTOR_END          = 16, /* #(と対応した) */
-            PS_BYTEVECTOR_START    = 17, /* #vu8( */
-            PS_BYTEVECTOR_END      = 18, /* #vu8(と対応した) */
-        };
-
         class Parser
         {
             // lexerを受け取り、lexerが保持する全体の解析を行いつつ、
@@ -54,7 +46,7 @@ namespace utakata {
             
         public:
             
-            Parser(smart_ptr<utakata::lexer::Lexer> l);
+            Parser(smart_ptr<lexer::Lexer> l);
             virtual ~Parser() {}
 
             // 受け取ったlexerからの字句の取得を行い、解析を行なう。
@@ -65,12 +57,81 @@ namespace utakata {
 
         private:
             smart_ptr<lexer::Lexer> lexer_;
+            // 各PARSERSTATUSに関連づけられたParserHandlerのmap
+            std::map<PARSERSTATUS, smart_ptr<IParserHandler> > handler_;
         };
 
         // 渡したlexemeがAbbrevationであるかどうかを調べる。
         bool isAbbrev(smart_ptr<lexeme::ILexeme> l);
         syntax::DatumID getAbbrevID(smart_ptr<lexeme::ILexeme> l);
 
+        // 各ハンドラの定義。
+
+        class InitHandler : public IParserHandler
+        {
+            // PS_INITに対応するハンドラ
+        public:
+            InitHandler() {}
+            virtual ~InitHandler() {}
+
+        private:
+
+            bool exec_(smart_ptr<syntax::Tree>& main,
+                       const smart_ptr<lexeme::ILexeme>& lexm,
+                       treestack& stack,
+                       std::stack<PARSERSTATUS>& status);
+
+        };
+
+        class ListHandler : public IParserHandler
+        {
+            // PS_LIST_CARである間に対応するハンドラ
+        public:
+            ListHandler() {}
+            virtual ~ListHandler() {}
+
+        private:
+
+            bool exec_(smart_ptr<syntax::Tree>& main,
+                       const smart_ptr<lexeme::ILexeme>& lexm,
+                       treestack& stack,
+                       std::stack<PARSERSTATUS>& status);
+
+        };
+
+        class DotHandler : public IParserHandler
+        {
+            // PS_AFTER_DOTに対応するハンドラ
+        public:
+            DotHandler() {}
+            virtual ~DotHandler() {}
+
+        private:
+
+            bool exec_(smart_ptr<syntax::Tree>& main,
+                       const smart_ptr<lexeme::ILexeme>& lexm,
+                       treestack& stack,
+                       std::stack<PARSERSTATUS>& status);
+
+        };
+
+        class AbbrevHandler : public IParserHandler
+        {
+            // PS_ABBREVIATIONに対応するハンドラ
+        public:
+            AbbrevHandler() {}
+            virtual ~AbbrevHandler() {}
+
+        private:
+
+            bool exec_(smart_ptr<syntax::Tree>& main,
+                       const smart_ptr<lexeme::ILexeme>& lexm,
+                       treestack& stack,
+                       std::stack<PARSERSTATUS>& status);
+
+        };
+
+
     };
 
 };
index f7635b1..3290ec2 100755 (executable)
@@ -1,19 +1,17 @@
-#include "parser_handler.h"
-#include "tree.h"
-
-using namespace std;
-using namespace utakata::parser;
-using namespace utakata::syntax;
-
-void ParserHandlerBase::exec(smart_ptr<syntax::Tree>& main,
-                             ParserHandlerBase::treestack& stack,
-                             std::stack<PARSERSTATUS>& status)
-{
-    return exec_(main, stack, status);
-}
-
-void ParserHandlerBase::exec_(smart_ptr<syntax::Tree>& main,
-                              ParserHandlerBase::treestack& stack,
-                              std::stack<PARSERSTATUS>& status)
-{
-}
+#include "parser_handler.h"\r
+#include "tree.h"\r
+#include "parser.h"\r
+#include "lexeme.h"\r
+\r
+using namespace std;\r
+using namespace utakata::parser;\r
+using namespace utakata::syntax;\r
+\r
+bool IParserHandler::exec(smart_ptr<syntax::Tree>& main,\r
+                          const smart_ptr<lexeme::ILexeme>& lexm,\r
+                          IParserHandler::treestack& stack,\r
+                          std::stack<PARSERSTATUS>& status)\r
+{\r
+    return exec_(main, lexm, stack, status);\r
+}\r
+\r
index c79d039..fe360c4 100755 (executable)
@@ -1,42 +1,50 @@
-#ifndef _PARSER_HANDLER_H_
-#define _PARSER_HANDLER_H_
-
-#include "smart_ptr.h"
-#include <stack>
-
-namespace utakata {
-
-    namespace syntax {
-        class Tree;
-    };
-    
-    namespace parser {
-
-        enum PARSERSTATUS;
-        class ParserHandlerBase
-        {
-            typedef std::stack<smart_ptr<syntax::Tree> > treestack;
-        public:
-            ParserHandlerBase() {}
-            virtual ~ParserHandleBase() {}
-
-            // 構文木のスタックとstatusのスタックを元に、Treeを
-            // 構築する。
-            void exec(smart_ptr<syntax::Tree>& main,
-                      treestack& stack,
-                      std::stack<PARSERSTATUS>& status);
-
-        private:
-
-            // 実際に起動される関数。
-            virtual void exec_(smart_ptr<syntax::Tree>& main,
-                               treestack& stack,
-                               std::stack<PARSERSTATUS>& status);
-
-        };
-
-    };
-
-};
-
-#endif /* _PARSER_HANDLER_H_ */
+#ifndef _PARSER_HANDLER_H_\r
+#define _PARSER_HANDLER_H_\r
+\r
+#include "smart_ptr.h"\r
+#include <stack>\r
+#include "parser_status.h"\r
+\r
+namespace utakata {\r
+\r
+    namespace syntax {\r
+        class Tree;\r
+    };\r
+\r
+    namespace lexeme {\r
+        class ILexeme;\r
+    }\r
+    \r
+    namespace parser {\r
+\r
+        class IParserHandler\r
+        {\r
+        public:\r
+            typedef std::stack<smart_ptr<syntax::Tree> > treestack;\r
+            IParserHandler() {}\r
+            virtual ~IParserHandler() {}\r
+\r
+            // \8d\\95\96Ø\82Ì\83X\83^\83b\83N\82Æstatus\82Ì\83X\83^\83b\83N\82ð\8c³\82É\81ATree\82ð\r
+            // \8d\\92z\82·\82é\81B\r
+            bool exec(smart_ptr<syntax::Tree>& main,\r
+                      const smart_ptr<lexeme::ILexeme>& lexm,\r
+                      treestack& stack,\r
+                      std::stack<PARSERSTATUS>& status);\r
+\r
+        private:\r
+\r
+            // \8eÀ\8dÛ\82É\8bN\93®\82³\82ê\82é\8aÖ\90\94\81B\r
+            // \8f\88\97\9d\82ª\8ds\82í\82ê\82½\8fê\8d\87\82É\82Ítrue\81A\8ds\82í\82ê\82È\82©\82Á\82½\8fê\8d\87\82É\82Ífalse\82ð\r
+            // \95Ô\82·\82±\82Æ\81B\r
+            virtual bool exec_(smart_ptr<syntax::Tree>& main,\r
+                               const smart_ptr<lexeme::ILexeme>& lexm,\r
+                               treestack& stack,\r
+                               std::stack<PARSERSTATUS>& status) = 0;\r
+\r
+        };\r
+\r
+    };\r
+\r
+};\r
+\r
+#endif /* _PARSER_HANDLER_H_ */\r
diff --git a/parser_status.h b/parser_status.h
new file mode 100755 (executable)
index 0000000..65f3131
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _PARSER_STATUS_H_\r
+#define _PARSER_STATUS_H_\r
+\r
+namespace utakata {\r
+    namespace parser {\r
+        enum PARSERSTATUS {\r
+            PS_INIT                = 0,  /* \8f\89\8aú\8e\9e\93_ */\r
+            PS_DATUM               = 1,  /* detum\82Å\82 \82é\82©\82Ç\82¤\82© */\r
+            PS_LEXEME_DATUM        = 2,  /* lexeme_detum\82Ì\82Ç\82ê\82©\82Å\82 \82é\82© */\r
+            PS_LIST_CAR            = 4,  /* \83\8a\83X\83g\82Ì\8aJ\8en - (,[ */\r
+            PS_LIST_END            = 5,  /* \83\8a\83X\83g\82Ì\8fI\97¹ - (,[\82Æ\91Î\89\9e\82·\82é),] */\r
+            PS_AFTER_DOT           = 6,  /* \83\8a\83X\83g\92\86\82É\8fo\8c»\82µ\82½ . */\r
+            PS_ABBREVIATION        = 7,  // abbrev syntax\82Ì\8cã\81B\r
+            PS_VECTOR_START        = 15, /* #( */\r
+            PS_VECTOR_END          = 16, /* #(\82Æ\91Î\89\9e\82µ\82½) */\r
+            PS_BYTEVECTOR_START    = 17, /* #vu8( */\r
+            PS_BYTEVECTOR_END      = 18, /* #vu8(\82Æ\91Î\89\9e\82µ\82½) */\r
+        };\r
+    };\r
+};\r
+\r
+#endif /* _PARSER_STATUS_H_ */\r
index 550cc01..b708041 100644 (file)
@@ -109,11 +109,11 @@ DIST_SOURCES = $(lexer_test_SOURCES) $(parser_test_SOURCES) \
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = ${SHELL} /home/derui/develop/utakata/missing --run aclocal-1.10
-AMTAR = ${SHELL} /home/derui/develop/utakata/missing --run tar
-AUTOCONF = ${SHELL} /home/derui/develop/utakata/missing --run autoconf
-AUTOHEADER = ${SHELL} /home/derui/develop/utakata/missing --run autoheader
-AUTOMAKE = ${SHELL} /home/derui/develop/utakata/missing --run automake-1.10
+ACLOCAL = ${SHELL} /home/derui/develop/sdl/missing --run aclocal-1.10
+AMTAR = ${SHELL} /home/derui/develop/sdl/missing --run tar
+AUTOCONF = ${SHELL} /home/derui/develop/sdl/missing --run autoconf
+AUTOHEADER = ${SHELL} /home/derui/develop/sdl/missing --run autoheader
+AUTOMAKE = ${SHELL} /home/derui/develop/sdl/missing --run automake-1.10
 AWK = gawk
 CC = gcc
 CCDEPMODE = depmode=gcc3
@@ -141,7 +141,7 @@ LDFLAGS =
 LIBOBJS = 
 LIBS = 
 LTLIBOBJS = 
-MAKEINFO = ${SHELL} /home/derui/develop/utakata/missing --run makeinfo
+MAKEINFO = ${SHELL} /home/derui/develop/sdl/missing --run makeinfo
 MKDIR_P = /bin/mkdir -p
 OBJEXT = o
 PACKAGE = utakata
@@ -155,10 +155,10 @@ SET_MAKE =
 SHELL = /bin/sh
 STRIP = 
 VERSION = 0.0.1
-abs_builddir = /home/derui/develop/utakata/test
-abs_srcdir = /home/derui/develop/utakata/test
-abs_top_builddir = /home/derui/develop/utakata
-abs_top_srcdir = /home/derui/develop/utakata
+abs_builddir = /home/derui/develop/sdl/test
+abs_srcdir = /home/derui/develop/sdl/test
+abs_top_builddir = /home/derui/develop/sdl
+abs_top_srcdir = /home/derui/develop/sdl
 ac_ct_CC = gcc
 ac_ct_CXX = g++
 am__include = include
@@ -178,7 +178,7 @@ host_alias =
 htmldir = ${docdir}
 includedir = ${prefix}/include
 infodir = ${datarootdir}/info
-install_sh = $(SHELL) /home/derui/develop/utakata/install-sh
+install_sh = $(SHELL) /home/derui/develop/sdl/install-sh
 libdir = ${exec_prefix}/lib
 libexecdir = ${exec_prefix}/libexec
 localedir = ${datarootdir}/locale
index 0b7577b..133a4df 100755 (executable)
--- a/tree.cpp
+++ b/tree.cpp
@@ -157,6 +157,9 @@ smart_ptr<utf8_string::UTF8String> Tree::toValue()
             }
         }
 
+        st.push(smart_ptr<UTF8String>(new UTF8String(
+                                          convert("|"))));
+
         t = s.top(); s.pop();
         if (s.size() == 0)
         {