OSDN Git Service

parser_testをDatumParserに対応。 master
authorderui <derutakayu@user.sourceforge.jp>
Sun, 28 Feb 2010 04:26:42 +0000 (13:26 +0900)
committerderui <derutakayu@user.sourceforge.jp>
Sun, 28 Feb 2010 04:26:42 +0000 (13:26 +0900)
DatumParserの内部を一部実装。
DatumParserの内部実装としてParserStateを作成。
旧parserの実装部分を削除。
構文違反のためのsyntax_error構造体を作成。
datum_tree及びdatum_tree_testを追加。

26 files changed:
Makefile
Rakefile
config.log
config.status
lib/binary_tree.h
lib/function.h
lib/meta_functional.h
lib/scoped_ptr.h
src/parser/datum.cpp
src/parser/datum.h
src/parser/datum_base.cpp
src/parser/datum_base.h
src/parser/datum_parser.cpp
src/parser/datum_parser.h
src/parser/datum_tree.cpp [new file with mode: 0644]
src/parser/datum_tree.h [new file with mode: 0644]
src/parser/parser.cpp.bk [deleted file]
src/parser/parser.h [deleted file]
src/parser/parser_handler.cpp.bk [deleted file]
src/parser/parser_handler.h [deleted file]
src/parser/parser_state.h [new file with mode: 0755]
src/parser/parser_status.h [deleted file]
src/parser/syntax_error.cpp [new file with mode: 0755]
src/parser/syntax_error.h [new file with mode: 0755]
test/datum_tree_test.cpp [new file with mode: 0755]
test/parser_test.cpp

index e52a6a9..b102303 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -69,11 +69,11 @@ DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 distuninstallcheck_listfiles = find . -type f -print
 distcleancheck_listfiles = find . -type f -print
-ACLOCAL = ${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run aclocal-1.10
-AMTAR = ${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run tar
-AUTOCONF = ${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run autoconf
-AUTOHEADER = ${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run autoheader
-AUTOMAKE = ${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run automake-1.10
+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
 AWK = gawk
 CC = gcc
 CCDEPMODE = depmode=gcc3
@@ -83,16 +83,16 @@ CPPFLAGS =
 CXX = g++
 CXXDEPMODE = depmode=gcc3
 CXXFLAGS = -g -O2
-CYGPATH_W = cygpath -w
+CYGPATH_W = echo
 DEFS = -DHAVE_CONFIG_H
 DEPDIR = .deps
 ECHO_C = 
 ECHO_N = -n
 ECHO_T = 
 EGREP = /bin/grep -E
-EXEEXT = .exe
+EXEEXT = 
 GREP = /bin/grep
-INSTALL = /bin/install -c
+INSTALL = /usr/bin/install -c
 INSTALL_DATA = ${INSTALL} -m 644
 INSTALL_PROGRAM = ${INSTALL}
 INSTALL_SCRIPT = ${INSTALL}
@@ -101,7 +101,7 @@ LDFLAGS =
 LIBOBJS = 
 LIBS = 
 LTLIBOBJS = 
-MAKEINFO = ${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run makeinfo
+MAKEINFO = ${SHELL} /home/derui/develop/utakata/missing --run makeinfo
 MKDIR_P = /bin/mkdir -p
 OBJEXT = o
 PACKAGE = utakata
@@ -115,10 +115,10 @@ SET_MAKE =
 SHELL = /bin/sh
 STRIP = 
 VERSION = 0.0.1
-abs_builddir = /cygdrive/c/meadow/develop/utakata
-abs_srcdir = /cygdrive/c/meadow/develop/utakata
-abs_top_builddir = /cygdrive/c/meadow/develop/utakata
-abs_top_srcdir = /cygdrive/c/meadow/develop/utakata
+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
 ac_ct_CC = gcc
 ac_ct_CXX = g++
 am__include = include
@@ -138,7 +138,7 @@ host_alias =
 htmldir = ${docdir}
 includedir = ${prefix}/include
 infodir = ${datarootdir}/info
-install_sh = $(SHELL) /cygdrive/c/meadow/develop/utakata/install-sh
+install_sh = $(SHELL) /home/derui/develop/utakata/install-sh
 libdir = ${exec_prefix}/lib
 libexecdir = ${exec_prefix}/libexec
 localedir = ${datarootdir}/locale
index f0f7384..e403d94 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -23,9 +23,9 @@ TEST_SRCS = FileList[File.join(TOP_DIR, "test/*.cpp")]
 TEST_OBJECTS = TEST_SRCS.ext("o")
 TEST_OBJECTS.include(OBJS)
 TEST_DEPS = TEST_SRCS.ext("mf")
-TEST_PROGRAMS = TEST_SRCS.ext(".exe")
+TEST_PROGRAMS = TEST_SRCS.ext("")
 
-EXEEXT = ".exe"
+EXEEXT = ""
 
 # lists of clean objects
 CLEAN.include(OBJS, TEST_OBJECTS, DEPS)
index e885965..76ef1ab 100644 (file)
@@ -10,16 +10,16 @@ generated by GNU Autoconf 2.63.  Invocation command line was
 ## Platform. ##
 ## --------- ##
 
-hostname = c2007
+hostname = vaio_z
 uname -m = i686
-uname -r = 1.7.1(0.218/5/3)
-uname -s = CYGWIN_NT-5.0
-uname -v = 2009-12-07 11:48
+uname -r = 2.6.32-gentoo-r1
+uname -s = Linux
+uname -v = #3 SMP Sat Jan 23 12:42:49 JST 2010
 
-/usr/bin/uname -p = unknown
+/usr/bin/uname -p = Intel(R) Core(TM)2 Duo CPU P8800 @ 2.66GHz
 /bin/uname -X     = unknown
 
-/bin/arch              = i686
+/bin/arch              = unknown
 /usr/bin/arch -k       = unknown
 /usr/convex/getsysinfo = unknown
 /usr/bin/hostinfo      = unknown
@@ -27,9 +27,7 @@ uname -v = 2009-12-07 11:48
 /usr/bin/oslevel       = unknown
 /bin/universe          = unknown
 
-PATH: /cygdrive/d/Program Files/OMake/bin
 PATH: /home/derui/bin
-PATH: /usr/local/stow/bin
 PATH: /usr/local/bin
 PATH: /usr/local/sbin
 PATH: /usr/sbin
@@ -46,7 +44,7 @@ PATH: /usr/X11R6/bin
 ## ----------- ##
 
 configure:1883: checking for a BSD-compatible install
-configure:1951: result: /bin/install -c
+configure:1951: result: /usr/bin/install -c
 configure:1962: checking whether build environment is sane
 configure:2005: result: yes
 configure:2030: checking for a thread-safe mkdir -p
@@ -57,11 +55,11 @@ configure:2109: result: gawk
 configure:2120: checking whether make sets $(MAKE)
 configure:2142: result: yes
 configure:2386: checking for g++
-configure:2402: found /bin/g++
+configure:2402: found /usr/bin/g++
 configure:2413: result: g++
 configure:2440: checking for C++ compiler version
 configure:2448: g++ --version >&5
-g++ (GCC) 4.3.4 20090804 (release) 1
+g++ (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4
 Copyright (C) 2008 Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -69,10 +67,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 configure:2452: $? = 0
 configure:2459: g++ -v >&5
 Using built-in specs.
-Target: i686-pc-cygwin
-Configured with: /gnu/gcc/releases/packaging/4.3.4-3/gcc4-4.3.4-3/src/gcc-4.3.4/configure --srcdir=/gnu/gcc/releases/packaging/4.3.4-3/gcc4-4.3.4-3/src/gcc-4.3.4 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --infodir=/usr/share/info --mandir=/usr/share/man --datadir=/usr/share --infodir=/usr/share/info --mandir=/usr/share/man -v --with-gmp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime-libs --with-slibdir=/usr/bin --libexecdir=/usr/lib --enable-static --enable-shared --enable-shared-libgcc --disable-__cxa_atexit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,objc,obj-c++ --disable-symvers --enable-libjava --program-suffix=-4 --enable-libgomp --enable-libssp --enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic --enable-libgcj-sublibs CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TARGET=g++-4 GNATMAKE_FOR_TARGET=gnatmake GNATBIND_FOR_TARGET=gnatbind AS=/opt/gcc-tools/bin/as.exe AS_FOR_TARGET=/opt/gcc-tools/bin/as.exe LD=/opt/gcc-tools/bin/ld.exe LD_FOR_TARGET=/opt/gcc-tools/bin/ld.exe --with-ecj-jar=/usr/share/java/ecj.jar
+Target: i686-pc-linux-gnu
+Configured with: /var/tmp/portage/sys-devel/gcc-4.3.4/work/gcc-4.3.4/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.3.4 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --disable-fixed-point --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --disable-libgcj --with-arch=i686 --enable-languages=c,c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.3.4 p1.0, pie-10.1.5'
 Thread model: posix
-gcc version 4.3.4 20090804 (release) 1 (GCC
+gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5
 configure:2463: $? = 0
 configure:2470: g++ -V >&5
 g++: '-V' option must have argument
@@ -80,17 +78,17 @@ configure:2474: $? = 1
 configure:2497: checking for C++ compiler default output file name
 configure:2519: g++    conftest.cpp  >&5
 configure:2523: $? = 0
-configure:2561: result: a.exe
+configure:2561: result: a.out
 configure:2580: checking whether the C++ compiler works
-configure:2590: ./a.exe
+configure:2590: ./a.out
 configure:2594: $? = 0
 configure:2613: result: yes
 configure:2620: checking whether we are cross compiling
 configure:2622: result: no
 configure:2625: checking for suffix of executables
-configure:2632: g++ -o conftest.exe    conftest.cpp  >&5
+configure:2632: g++ -o conftest    conftest.cpp  >&5
 configure:2636: $? = 0
-configure:2662: result: .exe
+configure:2662: result: 
 configure:2668: checking for suffix of object files
 configure:2694: g++ -c   conftest.cpp >&5
 configure:2698: $? = 0
@@ -108,11 +106,11 @@ configure:2989: result: GNU
 configure:3014: checking dependency style of g++
 configure:3105: result: gcc3
 configure:3168: checking for gcc
-configure:3184: found /bin/gcc
+configure:3184: found /usr/bin/gcc
 configure:3195: result: gcc
 configure:3427: checking for C compiler version
 configure:3435: gcc --version >&5
-gcc (GCC) 4.3.4 20090804 (release) 1
+gcc (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4
 Copyright (C) 2008 Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -120,10 +118,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 configure:3439: $? = 0
 configure:3446: gcc -v >&5
 Using built-in specs.
-Target: i686-pc-cygwin
-Configured with: /gnu/gcc/releases/packaging/4.3.4-3/gcc4-4.3.4-3/src/gcc-4.3.4/configure --srcdir=/gnu/gcc/releases/packaging/4.3.4-3/gcc4-4.3.4-3/src/gcc-4.3.4 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --infodir=/usr/share/info --mandir=/usr/share/man --datadir=/usr/share --infodir=/usr/share/info --mandir=/usr/share/man -v --with-gmp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime-libs --with-slibdir=/usr/bin --libexecdir=/usr/lib --enable-static --enable-shared --enable-shared-libgcc --disable-__cxa_atexit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,objc,obj-c++ --disable-symvers --enable-libjava --program-suffix=-4 --enable-libgomp --enable-libssp --enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic --enable-libgcj-sublibs CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TARGET=g++-4 GNATMAKE_FOR_TARGET=gnatmake GNATBIND_FOR_TARGET=gnatbind AS=/opt/gcc-tools/bin/as.exe AS_FOR_TARGET=/opt/gcc-tools/bin/as.exe LD=/opt/gcc-tools/bin/ld.exe LD_FOR_TARGET=/opt/gcc-tools/bin/ld.exe --with-ecj-jar=/usr/share/java/ecj.jar
+Target: i686-pc-linux-gnu
+Configured with: /var/tmp/portage/sys-devel/gcc-4.3.4/work/gcc-4.3.4/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.3.4 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.3.4/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --disable-fixed-point --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-multilib --enable-libmudflap --disable-libssp --enable-libgomp --disable-libgcj --with-arch=i686 --enable-languages=c,c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.3.4 p1.0, pie-10.1.5'
 Thread model: posix
-gcc version 4.3.4 20090804 (release) 1 (GCC
+gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5
 configure:3450: $? = 0
 configure:3457: gcc -V >&5
 gcc: '-V' option must have argument
@@ -183,9 +181,9 @@ configure:4285: result: /bin/grep -E
 configure:4290: checking for ANSI C header files
 configure:4320: gcc -c -g -O2  conftest.c >&5
 configure:4327: $? = 0
-configure:4426: gcc -o conftest.exe -g -O2   conftest.c  >&5
+configure:4426: gcc -o conftest -g -O2   conftest.c  >&5
 configure:4430: $? = 0
-configure:4436: ./conftest.exe
+configure:4436: ./conftest
 configure:4440: $? = 0
 configure:4458: result: yes
 configure:4482: checking for sys/types.h
@@ -232,8 +230,8 @@ configure:4660: checking for _Bool
 configure:4688: gcc -c -g -O2  conftest.c >&5
 configure:4695: $? = 0
 configure:4722: gcc -c -g -O2  conftest.c >&5
-conftest.c: In function ‘main’:
-conftest.c:56: error: expected expression before ‘)’ token
+conftest.c: In function 'main':
+conftest.c:56: error: expected expression before ')' token
 configure:4729: $? = 1
 configure: failed program was:
 | /* confdefs.h.  */
@@ -305,8 +303,8 @@ configure:4841: checking for size_t
 configure:4869: gcc -c -g -O2  conftest.c >&5
 configure:4876: $? = 0
 configure:4903: gcc -c -g -O2  conftest.c >&5
-conftest.c: In function ‘main’:
-conftest.c:58: error: expected expression before ‘)’ token
+conftest.c: In function 'main':
+conftest.c:58: error: expected expression before ')' token
 configure:4910: $? = 1
 configure: failed program was:
 | /* confdefs.h.  */
@@ -387,7 +385,7 @@ generated by GNU Autoconf 2.63.  Invocation command line was
   CONFIG_COMMANDS = 
   $ ./config.status 
 
-on c2007
+on vaio_z
 
 config.status:778: creating Makefile
 config.status:778: creating Rakefile
@@ -426,7 +424,6 @@ ac_cv_env_host_alias_set=
 ac_cv_env_host_alias_value=
 ac_cv_env_target_alias_set=
 ac_cv_env_target_alias_value=
-ac_cv_exeext=.exe
 ac_cv_header_inttypes_h=yes
 ac_cv_header_memory_h=yes
 ac_cv_header_stdbool_h=yes
@@ -441,7 +438,7 @@ ac_cv_header_unistd_h=yes
 ac_cv_objext=o
 ac_cv_path_EGREP='/bin/grep -E'
 ac_cv_path_GREP=/bin/grep
-ac_cv_path_install='/bin/install -c'
+ac_cv_path_install='/usr/bin/install -c'
 ac_cv_path_mkdir=/bin/mkdir
 ac_cv_prog_AWK=gawk
 ac_cv_prog_CPP='gcc -E'
@@ -460,14 +457,14 @@ am_cv_CXX_dependencies_compiler_type=gcc3
 ## Output variables. ##
 ## ----------------- ##
 
-ACLOCAL='${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run aclocal-1.10'
+ACLOCAL='${SHELL} /home/derui/develop/utakata/missing --run aclocal-1.10'
 AMDEPBACKSLASH='\'
 AMDEP_FALSE='#'
 AMDEP_TRUE=''
-AMTAR='${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run tar'
-AUTOCONF='${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run autoconf'
-AUTOHEADER='${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run autoheader'
-AUTOMAKE='${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run automake-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'
 AWK='gawk'
 CC='gcc'
 CCDEPMODE='depmode=gcc3'
@@ -477,14 +474,14 @@ CPPFLAGS=''
 CXX='g++'
 CXXDEPMODE='depmode=gcc3'
 CXXFLAGS='-g -O2'
-CYGPATH_W='cygpath -w'
+CYGPATH_W='echo'
 DEFS='-DHAVE_CONFIG_H'
 DEPDIR='.deps'
 ECHO_C=''
 ECHO_N='-n'
 ECHO_T=''
 EGREP='/bin/grep -E'
-EXEEXT='.exe'
+EXEEXT=''
 GREP='/bin/grep'
 INSTALL_DATA='${INSTALL} -m 644'
 INSTALL_PROGRAM='${INSTALL}'
@@ -494,7 +491,7 @@ LDFLAGS=''
 LIBOBJS=''
 LIBS=''
 LTLIBOBJS=''
-MAKEINFO='${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run makeinfo'
+MAKEINFO='${SHELL} /home/derui/develop/utakata/missing --run makeinfo'
 MKDIR_P='/bin/mkdir -p'
 OBJEXT='o'
 PACKAGE='utakata'
@@ -531,7 +528,7 @@ host_alias=''
 htmldir='${docdir}'
 includedir='${prefix}/include'
 infodir='${datarootdir}/info'
-install_sh='$(SHELL) /cygdrive/c/meadow/develop/utakata/install-sh'
+install_sh='$(SHELL) /home/derui/develop/utakata/install-sh'
 libdir='${exec_prefix}/lib'
 libexecdir='${exec_prefix}/libexec'
 localedir='${datarootdir}/locale'
index 4bbfd37..e1726bb 100755 (executable)
@@ -363,9 +363,9 @@ 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='/cygdrive/c/meadow/develop/utakata'
+ac_pwd='/home/derui/develop/utakata'
 srcdir='.'
-INSTALL='/bin/install -c'
+INSTALL='/usr/bin/install -c'
 MKDIR_P='/bin/mkdir -p'
 AWK='gawk'
 test -n "$AWK" || AWK=awk
@@ -554,7 +554,7 @@ S["am__quote"]=""
 S["am__include"]="include"
 S["DEPDIR"]=".deps"
 S["OBJEXT"]="o"
-S["EXEEXT"]=".exe"
+S["EXEEXT"]=""
 S["ac_ct_CXX"]="g++"
 S["CPPFLAGS"]=""
 S["LDFLAGS"]=""
@@ -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} /cygdrive/c/meadow/develop/utakata/missing --run tar"
+S["AMTAR"]="${SHELL} /home/derui/develop/utakata/missing --run tar"
 S["am__leading_dot"]="."
 S["SET_MAKE"]=""
 S["AWK"]="gawk"
@@ -570,15 +570,15 @@ 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) /cygdrive/c/meadow/develop/utakata/install-sh"
-S["MAKEINFO"]="${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run makeinfo"
-S["AUTOHEADER"]="${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run autoheader"
-S["AUTOMAKE"]="${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run automake-1.10"
-S["AUTOCONF"]="${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run autoconf"
-S["ACLOCAL"]="${SHELL} /cygdrive/c/meadow/develop/utakata/missing --run aclocal-1.10"
+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["VERSION"]="0.0.1"
 S["PACKAGE"]="utakata"
-S["CYGPATH_W"]="cygpath -w"
+S["CYGPATH_W"]="echo"
 S["am__isrc"]=""
 S["INSTALL_DATA"]="${INSTALL} -m 644"
 S["INSTALL_SCRIPT"]="${INSTALL}"
index fa7d7fb..d0fc8e1 100755 (executable)
@@ -23,10 +23,10 @@ namespace binary_tree_detail {
 // 実際にアクセスすることはできません。
 template <typename T>
 struct node {
-  node() : parent_(NULL), left_(NULL), right_(NULL), 
-           next_sibling_(NULL), prev_sibling_(NULL), data_() {}
-  node(const T& data) : parent_(NULL), left_(NULL), right_(NULL),
-                        next_sibling_(NULL), prev_sibling_(NULL),
+  node() : parent_(0), left_(0), right_(0), 
+           next_sibling_(0), prev_sibling_(0), data_() {}
+  node(const T& data) : parent_(0), left_(0), right_(0),
+                        next_sibling_(0), prev_sibling_(0),
                         data_(data) {}
   node<T>* parent_;
   node<T>* left_;
@@ -34,7 +34,7 @@ struct node {
   // 同じ親に接続されている前後のnodeを指します。
   // ただし、二分木の場合、左ノードの場合はnext_sibling_に右ノードが、
   // 右ノードの場合はpref_sibling_に左ノードが設定され、
-  // それぞれprev/nextはNULLが設定されます。
+  // それぞれprev/nextは0が設定されます。
   node<T>* next_sibling_;
   node<T>* prev_sibling_;
 
@@ -66,7 +66,7 @@ struct pre_order {
       return true;
     }
 
-    while (now_target->next_sibling_ == NULL) {
+    while (now_target->next_sibling_ == 0) {
       if (!now_target->parent_) {
         return false;
       }
@@ -76,7 +76,7 @@ struct pre_order {
   }
 
   // 渡されたtargetから、次に進むべきデータを返します。
-  // has_nextがfalseを返却する場合、NULLが返却されます。
+  // has_nextがfalseを返却する場合、0が返却されます。
   node<T>* next(node<T>* target) {
     if (target->left_) {
       return target->left_;
@@ -85,9 +85,9 @@ struct pre_order {
     }
 
     node<T>* now_target = target;
-    while (now_target->next_sibling_ == NULL) {
+    while (now_target->next_sibling_ == 0) {
       now_target = now_target->parent_;
-      if (now_target == NULL) {
+      if (now_target == 0) {
         return now_target;
       }
     }
@@ -116,7 +116,7 @@ class binary_tree {
   struct iterator {
 
     // コピーコンストラクタ、及びデフォルトコンストラクタです。
-    iterator() : node_(NULL), traverser_() {}
+    iterator() : node_(0), traverser_() {}
     iterator(const iterator& it) : node_(it.node_),
                                    traverser_(it.traverser_) {}
     explicit iterator(binary_tree_detail::node<T>* convert) : node_(convert), traverser_() {}
@@ -161,17 +161,17 @@ class binary_tree {
   // 番兵として機能するend_を設定します。
   binary_tree() : root_(new binary_tree_detail::node<T>()),
                   end_(new binary_tree_detail::node<T>()) {
-    root_->parent_ = NULL;
-    root_->left_   = NULL;
-    root_->right_  = NULL;
+    root_->parent_ = 0;
+    root_->left_   = 0;
+    root_->right_  = 0;
     root_->next_sibling_ = end_;
-    root_->prev_sibling_ = NULL;
+    root_->prev_sibling_ = 0;
 
-    end_->parent_ = NULL;
-    end_->left_ = NULL;
-    end_->right_ = NULL;
+    end_->parent_ = 0;
+    end_->left_ = 0;
+    end_->right_ = 0;
     end_->prev_sibling_ = root_;
-    end_->next_sibling_ = NULL;
+    end_->next_sibling_ = 0;
   }
 
   virtual ~binary_tree() {
index 0b9e73d..fe782b8 100644 (file)
@@ -36,9 +36,9 @@ class function<R()> {
 
   // 関数ポインタの場合に該当する、関数ポインタの実行、及び開放関数を
   // 保持するためのType Erasurerです。
-  template<class Func, class R>
+  template<class Func, typename Result>
   struct function_ptr_manager {
-    static R invoke(any_pointer function_ptr) {
+    static Result invoke(any_pointer function_ptr) {
       Func func = reinterpret_cast<Func>(function_ptr.func_ptr);
       return func();
     }
@@ -48,9 +48,9 @@ class function<R()> {
 
   // 関数オブジェクトの場合に該当する関数オブジェクトの実行、及び開放関数を
   // 保持するためのType Erasurerです。
-  template <typename Func, class R>
+  template <typename Func, class Result>
   struct function_obj_manager {
-    static R invoke(any_pointer func_obj) {
+    static Result invoke(any_pointer func_obj) {
       Func* func = reinterpret_cast<Func*>(func_obj.obj_ptr);
       return (*func)();
     }
index f21ab3a..23a5e44 100644 (file)
@@ -48,7 +48,7 @@ struct add_const {
 template<class T>
 struct add_const_reference {
   // 指定された型にconst &を付与した型を提供するメタ関数です。
-  typedef typename add_const<typename add_reference<T>::type> >::type type;
+  typedef typename add_const<typename add_reference<T>::type>::type type;
 };
 
 template<class T>
@@ -78,13 +78,13 @@ struct remove_const<const T> {
 template <bool Cond, class Then, class Else>
 struct if_c;
 
-template<class Then, class Else>
-struct if_c<true> {
+template <class Then, class Else>
+struct if_c<true, Then, Else> {
   typedef Then type;
 };
 
-template<class Then, class Else>
-struct if_c<false> {
+template <class Then, class Else>
+struct if_c<false, Then, Else> {
   typedef Else type;
 };
 
@@ -121,11 +121,6 @@ struct is_void<void> {
 // iterator型が存在する場合、::valueとしてtrueを返します。
 template<class T>
 class has_iterator {
- public:
-  // test<T>(0)は、test()関数に型適用を施して呼び出し、結果の型
-  // を取得する構文です。
-  static const bool value = sizeof(test<T>(0)) == sizeof(yes);
- private:
 
   // iterator型が存在する場合に返される型です。
   typedef char yes;
@@ -141,16 +136,16 @@ class has_iterator {
   // iterator型を保持していない場合、こちらが適用されます。
   template <typename C>
   static no test(...);
-};
 
-// reverse_iterator型が存在する場合、::valueとしてtrueを返します。
-template<class T>
-class has_reverse_iterator {
  public:
   // test<T>(0)は、test()関数に型適用を施して呼び出し、結果の型
   // を取得する構文です。
   static const bool value = sizeof(test<T>(0)) == sizeof(yes);
- private:
+};
+
+// reverse_iterator型が存在する場合、::valueとしてtrueを返します。
+template<class T>
+class has_reverse_iterator {
 
   // iterator型が存在する場合に返される型です。
   typedef char yes;
@@ -166,6 +161,11 @@ class has_reverse_iterator {
   // iterator型を保持していない場合、こちらが適用されます。
   template <typename C>
   static no test(...);
+
+ public:
+  // test<T>(0)は、test()関数に型適用を施して呼び出し、結果の型
+  // を取得する構文です。
+  static const bool value = sizeof(test<T>(0)) == sizeof(yes);
 };
 
 
index 534f9a1..3234c35 100755 (executable)
@@ -43,9 +43,7 @@ class scoped_ptr : private uncopyable {
   // 引数が指定されない場合、NULLがデフォルト引数となります。
   void reset(T* p = NULL) {
     if (p != obj_) {
-      if (sizeof(T) > 0) {
-        delete obj_;
-      }
+      delete obj_;
       obj_ = p;
     }
   }
index e515570..49f8229 100644 (file)
@@ -2,13 +2,18 @@
 #include "src/exception_std.h"
 #include "src/parser/datum.h"
 #include "src/unicode.h"
+#include "src/lexer/token.h"
 
 namespace datum = utakata::datum;
 namespace unicode = utakata::unicode;
 namespace exception = utakata::exception;
+namespace lexer = utakata::lexer;
 
 /// To string datum
 
+datum::String::String(const lexer::Token& token, const unicode::UniString& string)
+: datum::Datum(token), string_(new unicode::UniString(string)) {}
+
 // 宣言のコメントを参照してください。
 const unicode::UniString& datum::String::ToString() const {
   return *string_;
@@ -24,13 +29,12 @@ const unicode::UniString& datum::String::GetString() const {
   return *string_;
 }
 
-// 宣言のコメントを参照してください。
-const lexer::Token& datum::String::GetBaseToken() const {
-  return *token_;
-}
-
 /// To symbol datum
 
+datum::Symbol::Symbol(const lexer::Token& token,
+                      const unicode::UniString& symbol)
+: datum::Datum(token), symbol_(new unicode::UniString(symbol)) {}
+
 // 宣言のコメントを参照してください。
 const unicode::UniString& datum::Symbol::ToString() const {
   return *symbol_;
@@ -46,12 +50,13 @@ const unicode::UniString& datum::Symbol::GetSymbolName() const {
   return *symbol_;
 }
 
-// 宣言のコメントを参照してください。
-const lexer::Token& datum::String::GetBaseToken() const {
-  return *token_;
-}
-
 // To charactor datum
+datum::Charactor::Charactor(const lexer::Token& token,
+                            const unicode::UniChar& charactor,
+                            const unicode::UniString& charactor_name)
+: datum::Datum(token), 
+  charactor_(new unicode::UniChar(charactor)),
+  charactor_name_(new unicode::UniString(charactor_name)) {}
 
 // 宣言のコメントを参照してください。
 const unicode::UniString& datum::Charactor::ToString() const {
@@ -68,16 +73,15 @@ const unicode::UniChar& datum::Charactor::GetCharactor() const {
   return *charactor_;
 }
 
-// 宣言のコメントを参照してください。
-const lexer::Token& datum::String::GetBaseToken() const {
-  return *token_;
-}
-
 // To boolean datum
 
+datum::Boolean::Boolean(const lexer::Token& token,
+                        bool auth)
+: datum::Datum(token), boolean_value_(auth) {}
+
 // 宣言のコメントを参照してください。
 const unicode::UniString& datum::Boolean::ToString() const {
-  return *original_string_;
+  return token().string();
 }
 
 // 宣言のコメントを参照してください。
@@ -85,17 +89,16 @@ datum::IDatumBase* datum::Boolean::Eval(interpreter::Environment* env) {
   return NULL;
 }
 
-// 宣言のコメントを参照してください。
-const lexer::Token& datum::String::GetBaseToken() const {
-  return *token_;
-}
-
 /////////////////////
 // To number datum //
 /////////////////////
+
+datum::Number::Number(const lexer::Token& token, int number)
+: datum::Datum(token), tmp_number_(number) {}
+
 // 宣言のコメントを参照してください。
 const unicode::UniString& datum::Number::ToString() const {
-  return *original_string_;
+  return token().string();
 }
 
 // 宣言のコメントを参照してください。
@@ -103,7 +106,46 @@ datum::IDatumBase* datum::Number::Eval(interpreter::Environment* env) {
   return NULL;
 }
 
-// 宣言のコメントを参照してください。
-const lexer::Token& datum::String::GetBaseToken() const {
-  return *token_;
+int datum::Number::GetNumber() const {return tmp_number_;}
+
+void datum::Number::SetNumber(int num) {tmp_number_ = num;}
+
+// 宣言のコメントを参照してください
+datum::Cons::Cons(const lexer::Token& token) : datum::Datum(token) {}
+
+// ConsのToStringでは、内部構造の構造上の理由により、有効な文字列は返却されません。
+const unicode::UniString& datum::Cons::ToString() const {
+  return token().string();
+}
+
+// 宣言のコメントを参照してください
+datum::IDatumBase* datum::Cons::Eval(interpreter::Environment* env) {
+  return NULL;
+}
+
+// 宣言のコメントを参照してください
+datum::Vector::Vector(const lexer::Token& token) : datum::Datum(token) {}
+
+// VectorのToStringでは、内部構造の構造上の理由により、有効な文字列は返却されません。
+const unicode::UniString& datum::Vector::ToString() const {
+  return token().string();
+}
+
+// 宣言のコメントを参照してください
+datum::IDatumBase* datum::Vector::Eval(interpreter::Environment* env) {
+  return NULL;
+}
+
+// 宣言のコメントを参照してください
+datum::Bytevector::Bytevector(const lexer::Token& token) : datum::Datum(token) {}
+
+// BytevectorのToStringでは、内部構造の構造上の理由により、有効な文字列は返却されません。
+const unicode::UniString& datum::Bytevector::ToString() const {
+  return token().string();
 }
+
+// 宣言のコメントを参照してください
+datum::IDatumBase* datum::Bytevector::Eval(interpreter::Environment* env) {
+  return NULL;
+}
+
index ca63923..3046064 100755 (executable)
@@ -16,6 +16,10 @@ class UniString;
 class UniChar;
 }
 
+namespace lexer {
+class Token;
+}  // namespace lexer
+
 namespace datum {
 
 class Environment;
@@ -26,9 +30,7 @@ class Environment;
 // ます。
 class String : public Datum {
  public:
-  String(const lexer::Token& token, const unicode::UniString& string)
-      : Datum(token),
-        string_(new unicode::UniString(string)) {}
+  String(const lexer::Token& token, const unicode::UniString& string);
   virtual ~String() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -54,9 +56,7 @@ class String : public Datum {
 // stringと同じく、symbolを構成する文字列のみを保持します。
 class Symbol : public Datum {
  public:
-  Symbol(const lexer::Token& token, const unicode::UniString& symbol)
-      : Datum(token),
-        symbol_(new unicode::UniString(symbol)) {}
+  Symbol(const lexer::Token& token, const unicode::UniString& symbol);
   virtual ~Symbol() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -79,11 +79,8 @@ class Symbol : public Datum {
 class Charactor : public Datum {
  public:
   Charactor(const lexer::Token& token,
-            const unicode::UniString& charactor_name,
-            const unicode::UniChar& charactor)
-      : Datum(token),
-        charactor_(new unicode::UniChar(charactor)),
-        charactor_name_(new unicode::UniString(charactor_name)) {}
+            const unicode::UniChar& charactor,
+            const unicode::UniString& charactor_name);
   virtual ~Charactor() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -114,9 +111,7 @@ class Charactor : public Datum {
 // そのように変更される場合があります。
 class Boolean : public datum::Datum {
  public:
-  Boolean(const lexer::Token& token, const unicode::UniString& base, bool auth)
-      : Datum(token),
-        boolean_value_(auth), original_string_(new unicode::UniString(base)) {}
+  Boolean(const lexer::Token& token, bool auth);
   virtual ~Boolean() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -137,9 +132,6 @@ class Boolean : public datum::Datum {
 
   // 真偽値を直接保存します。
   bool boolean_value_;
-
-  // 真偽値の文字列をそのまま保存します。
-  akebono::scoped_ptr<unicode::UniString> original_string_;
 };
 
 // datum syntaxにおける<number>を表現します。
@@ -149,9 +141,7 @@ class Boolean : public datum::Datum {
 // そのように変更される場合があります。
 class Number : public datum::Datum {
  public:
-  Number(const lexer::Token& token, const unicode::UniString& base, int number)
-      : Datum(token),
-        tmp_number_(number), original_string_(new unicode::UniString(base)) {}
+  Number(const lexer::Token& token, int number);
   virtual ~Number() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -170,22 +160,17 @@ class Number : public datum::Datum {
 
   virtual datum::DatumType type() const {return datum::kNumber;}
 
-  virtual const lexer::Token& GetBaseToken() const;
-
  private:
 
   // 数値オブジェクトを設定します。
   int tmp_number_;
-
-  // 真偽値の文字列をそのまま保存します。
-  akebono::scoped_ptr<unicode::UniString> original_string_;
 };
 
 // compound datum内のlist>を構築するためのconsセルです。
 // Consセル自体はいかなるデータも保存しません。
 class Cons : public datum::Datum {
  public:
-  explicit Cons(const lexer::Token& token) : Datum(token) {}
+  explicit Cons(const lexer::Token& token);
   virtual ~Cons() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -206,7 +191,7 @@ class Cons : public datum::Datum {
 // しているのみとなります。
 class Vector : public datum::Datum {
 public:
-  explicit Vector(const lexer::Token& token) : Datum(token) {}
+  explicit Vector(const lexer::Token& token);
   virtual ~Vector() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -226,8 +211,7 @@ public:
 // 行いません。
 class Bytevector : public datum::Datum {
 public:
-  explicit Bytevector(const lexer::Token& token)
-      : Datum(token), datum_list_() {}
+  explicit Bytevector(const lexer::Token& token);
   virtual ~Bytevector() {}
 
   // このオブジェクトの文字列表現を返します。
@@ -239,13 +223,13 @@ public:
   virtual datum::IDatumBase* Eval(interpreter::Environment* env);
 
   // 内部で保持しているdatumのvectorを返します。
-  virtual const std::vector<akebono::smart_ptr<Datum> >& GetBytevector() const {
+  virtual const std::vector<akebono::smart_ptr<IDatumBase> >& GetBytevector() const {
     return datum_list_;
   }
 
   // 渡されたvectorを設定します。
   virtual void SetBytevector(
-      const std::vector<akebono::smart_ptr<Datum> >& vector) {
+      const std::vector<akebono::smart_ptr<IDatumBase> >& vector) {
     datum_list_ = vector;
   }
 
@@ -256,7 +240,7 @@ public:
   // 内部に内包しているDatumのリストとなります。
   // 内部に内包することが可能なのは、任意のdatumであるため、この時点
   // では一意に確定はしません。
-  std::vector<akebono::smart_ptr<Datum> > datum_list_;
+  std::vector<akebono::smart_ptr<IDatumBase> > datum_list_;
 };
 
 }
index 4e0ad6b..f676654 100644 (file)
@@ -1,3 +1,4 @@
+#include "src/lexer/token.h"
 #include "src/exception_macro.h"
 #include "src/exception_std.h"
 #include "src/parser/datum.h"
@@ -6,6 +7,7 @@
 namespace datum = utakata::datum;
 namespace unicode = utakata::unicode;
 namespace exception = utakata::exception;
+namespace lexer = utakata::lexer;
 
 // 宣言のコメントを参照して下さい。
 bool datum::IDatumBase::GetBoolean() const {
@@ -50,24 +52,15 @@ const unicode::UniChar& datum::IDatumBase::GetCharactor() const {
 }
 
 // 宣言のコメントを参照して下さい。
-const std::vector<datum::IDatumBase*>& datum::IDatumBase::GetVector() const {
-  THROW_EXCEPTION_(exception::NotImplementedException,
-                   unicode::Convert("Not implemented `GetVector`"));
-}
-
-void datum::IDatumBase::SetVector(const std::vector<datum::IDatumBase*>& vector) {
-  THROW_EXCEPTION_(exception::NotImplementedException,
-                   unicode::Convert("Not implemented `SetVector`"));
-}
-
-// 宣言のコメントを参照して下さい。
-const std::vector<datum::IDatumBase*>& datum::IDatumBase::GetBytevector() const {
+const std::vector<akebono::smart_ptr<datum::IDatumBase> >&
+datum::IDatumBase::GetBytevector() const {
   THROW_EXCEPTION_(exception::NotImplementedException,
                    unicode::Convert("Not implemented `GetBytevector`"));
 }
 
 // 宣言のコメントを参照して下さい。
-void datum::IDatumBase::SetBytevector(const std::vector<datum::IDatumBase*>& vector) {
+void datum::IDatumBase::SetBytevector(
+    const std::vector<akebono::smart_ptr<datum::IDatumBase> >& vector) {
   THROW_EXCEPTION_(exception::NotImplementedException,
                    unicode::Convert("Not implemented `SetBytevector`"));
 }
@@ -78,6 +71,6 @@ datum::Datum::Datum(const lexer::Token& token)
     : token_(new lexer::Token(token)) {}
 
 // 宣言のコメントを参照して下さい
-const lexer::Token& datum::Datum::GetBaseToken() const {
+const lexer::Token& datum::Datum::token() const {
   return *token_;
 }
index f27ebbd..c5a17bc 100755 (executable)
@@ -17,6 +17,10 @@ class UniString;
 class UniChar;
 }
 
+namespace lexer {
+class Token;
+}  // namespace lexer
+
 namespace interpreter {
 class Environment;
 } // end of namespace interpreter
@@ -115,7 +119,7 @@ class IDatumBase : private akebono::uncopyable {
   virtual datum::DatumType type() const = 0;
 
   // datumが構築された時に元となったTokenを返却します。
-  virtual const lexer::Token& GetBaseToken() const = 0;
+  virtual const lexer::Token& token() const = 0;
 };
 
 
@@ -128,7 +132,7 @@ class Datum : public IDatumBase {
   virtual ~Datum() {}
 
   // datumが構築された時に元となったTokenを返却します。
-  virtual const lexer::Token& GetBaseToken() const;
+  virtual const lexer::Token& token() const;
 
  private:
 
index 0183c2f..6879f8d 100755 (executable)
-// #include "src/parser/datum_parser.h"
-
-// #include "parser.h"
-// #include "lexeme.h"
-// #include "lexeme_data.h"
-// #include "lexer.h"
-// #include "lexeme_id.h"
-// #include "datum_id.h"
-// #include "reader.h"
-// #include "object.h"
-// #include "gc.h"
-// #include "primitive.h"
-// #include "primitive_class.h"
-// #include "primitive_util.h"
-// #include "data_castor.h"
-
-// using namespace utakata;
-// using namespace utakata::parser;
-// using namespace utakata::lexeme;
-// using namespace utakata::interpreter;
-
-// parser::DatumException::DatumException(std::string str) : str_()
-// {
-//     // エラーメッセージを定義する。
-//     std::stringstream ss;
-//     ss << "datum error ! -- message : [" << str << "]" << std::endl;
-//     str_ = ss.str();
-// }
-
-// const char* parser::DatumException::what() const throw()
-// {
-//     return str_.c_str();
-// }
-
-// ////////////////////////////
-// // Parser Implementations //
-// ///////////////////////////
-
-// 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;
-//     p.second.add(new ListHandler);
-//     handler_.insert(p);
-
-//     // .内用ハンドラの設定
-//     p.first = PS_END_DOT;
-//     p.second.add(new DotEndHandler);
-//     handler_.insert(p);
-
-//     // abbreviation 用ハンドラの設定
-//     p.first = PS_ABBREVIATION;
-//     p.second.add(new AbbrevHandler);
-//     handler_.insert(p);
-
-//     // error 用のハンドラの設定
-//     p.first = PS_ERROR;
-//     p.second.add(new ErrorHandler);
-//     handler_.insert(p);
-// }
-
-// smart_ptr<data::Object> parser::Parser::parse(smart_ptr<reader::StreamReader>& strm,
-//                                               gc::GarbageCollector& gc)
-// {
-//     HandlerData data(gc);
-//     data.status.push(PS_INIT);
-
-//     while(!data.status.empty()) {
-
-//         if(data.status.top() != PS_ERROR)
-//         {
-//             if (data.chain)
-//             {
-//                 data.chain = false;
-//             }
-//             else
-//             {
-//                 data.lexm = lexer_->lex(strm);
-//             }
-            
-//             if(data.lexm.isNull() ||
-//                data.lexm->getID() == lexeme::LexemeID::eos)
-//             {
-//                 break;
-//             }
-//             // 基本的にすべてハンドラに任せる。
-//             handler_[data.status.top()]->exec(data);
-//         }
-//         else
-//         {
-//             // ERROR だったら、強制的にハンドラを回してループから抜ける。
-//             handler_[data.status.top()]->exec(data);
-//         }
-//     }
-
-//     // stackのtopにはmainが殘ったままなので、data.stackのtopを追加してやる。
-//     smart_ptr<data::Object> ret(new data::Object(data.stack.top()));
-//     return ret;
-// }
-
-// bool parser::isAbbrev(smart_ptr<lexeme::ILexeme> l)
-// {
-//     // abbreviation かどうかを判別する。
-//     switch(l->getID().toEnum())
-//     {
-//     case lexeme::LexemeID::BACKQUOTE:        return true;
-//     case lexeme::LexemeID::QUOTE:            return true;
-//     case lexeme::LexemeID::UNQUOTE:          return true;
-//     case lexeme::LexemeID::UNQUOTESPLICING:  return true;
-//     case lexeme::LexemeID::SYNTAX:           return true;
-//     case lexeme::LexemeID::QUASISYNTAX:      return true;
-//     case lexeme::LexemeID::UNSYNTAX:         return true;
-//     case lexeme::LexemeID::UNSYNTAXSPLICING: return true;
-//     default:
-//         return false;
-//     }
-// }
-
-// interpreter::IObject* parser::makePrimitiveFromLexeme(smart_ptr<lexeme::ILexeme> l)
-// {
-//     // 各lexemeに対応した固定lexemeを返す。
-//     interpreter::IObject* o = NULL;
-//     switch (l->getID().toEnum())
-//     {
-//     case lexeme::LexemeID::STRING:
-//         return util::makeString(l->getData()->string->str);
-//     case lexeme::LexemeID::CHARACTOR:
-//         return util::makeCharactor(l->getData()->charactor->spec);
-//     case lexeme::LexemeID::IDENTIFIER:
-//         return util::makeSymbol(l->getData()->symbol->id);
-//     case lexeme::LexemeID::BOOLEAN:
-//         return util::makeBoolean(l->getData()->boolean->boolean);
-//     case lexeme::LexemeID::NUMBER:
-//     {
-//         lexeme::NumberData& t = *(l->getData()->number);
-//         return util::makeNumber(t.real, t.imagin, t.exact,
-//                                 t.radix);
-//     }
-//     case lexeme::LexemeID::BACKQUOTE:
-//         return util::Abbrev<primitive::Quasiquote>::make();
-//     case lexeme::LexemeID::QUOTE:
-//         return util::Abbrev<primitive::Quote>::make();
-//     case lexeme::LexemeID::UNQUOTE:
-//         return util::Abbrev<primitive::Unquote>::make();
-//     case lexeme::LexemeID::UNQUOTESPLICING:
-//         return util::Abbrev<primitive::UnquoteSplicing>::make();
-//     case lexeme::LexemeID::SYNTAX:
-//         return util::Abbrev<primitive::Syntax>::make();
-//     case lexeme::LexemeID::QUASISYNTAX:
-//         return util::Abbrev<primitive::Quasisyntax>::make();
-//     case lexeme::LexemeID::UNSYNTAX:
-//         return util::Abbrev<primitive::Unsyntax>::make();
-//     case lexeme::LexemeID::UNSYNTAXSPLICING:
-//         return util::Abbrev<primitive::UnsyntaxSplicing>::make();
-//     default:
-//         break;
-//     }
-
-//     return o;
-// }
-
-// /////////////////////
-// // parser handlers //
-// /////////////////////
-
-// bool InitHandler::exec_(HandlerData& data)
-// {
-//     data.status.pop();
-//     // 初期状態の解釈処理を行う。
-//     if(data.lexm->getID() == lexeme::LexemeID::openParenthesis)
-//     {
-//         // 開き括弧である場合、compoundsに新しくpushして返る。
-//         data.compounds.push(std::vector<data::Object>());
-//         data.status.push(PS_LIST);
-//     }
-//     else if(data.lexm->getID() == lexeme::LexemeID::string ||
-//             data.lexm->getID() == lexeme::LexemeID::number ||
-//             data.lexm->getID() == lexeme::LexemeID::identifier ||
-//             data.lexm->getID() == lexeme::LexemeID::charactor ||
-//             data.lexm->getID() == lexeme::LexemeID::boolean)
-//     {
-//         // それぞれの場合、単純にstackに各オブジェクトをpushする。
-
-//         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))
-//     {
-//         // abbreviation である場合には、 全体をリストに展開するため、carまでは
-//         // 設定された状態にする。
-//         std::vector<data::Object> v;
-//         v.push_back(data::Object(false,
-//                                  data.gc.add(makePrimitiveFromLexeme(data.lexm))));
-
-//         data.compounds.push(v);
-
-//         // status stack に、 PS_ABBREVIATIONとPS_INITを積む。
-//         data.status.push(PS_ABBREVIATION);
-//         data.status.push(PS_INIT);
-//     }
-//     else
-//     {
-//         throw DatumException("datum の開始記号ではありません");
-//     }
-
-//     return true;
-// }
-
-// // List 内部処理のハンドリング
-
-// bool ListHandler::exec_(HandlerData& data)
-// {
-//     // list の開始部分である場合。
-//     if(data.lexm->getID() == lexeme::LexemeID::openParenthesis)
-//     {
-//         // 更にcompoundsに追加して積む。
-//         data.compounds.push(std::vector<data::Object>());
-//         data.status.push(PS_LIST);
-//     }
-//     else if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis)
-//     {
-//         // 原則として、閉括弧が来た時点で終了とするだけでよい。
-//         // 現在のtopにあるcompoundsが、データであるとされているため、
-//         // とりあえずtopにあるvectorをConsの繋がりに変換する。
-
-//         std::vector<data::Object> v = data.compounds.top(); data.compounds.pop();
-//         // vectorをConsへと変換するには、次のようにして後ろからやっていく
-//         // 方式が一番面倒がない。
-//         // 1. cdrをnil、carをvectorの末尾であるデータとしたconsを作成する。
-//         // 2. vectorの次のデータをcar、前のconsをcdrとしたconsを作成する。
-//         // 3. 先頭まで続ける。
-
-//         if (v.size() == 0)
-//         {
-//             // サイズが0の場合には、nilを設定する。
-//             data::Object o = data::Object(false,
-//                                           data.gc.add(util::makeNil()));
-//             pushList(data, o);
-//         }
-//         else
-//         {
-//             // 後ろから前に向かっていく。
-//             std::vector<data::Object>::reverse_iterator begin = v.rbegin(),
-//                 end = v.rend();
-//             // ちょっと面倒すぎるなこれ。
-//             data::Object o = data::Object(
-//                 false, data.gc.add(
-//                     util::makeCons(*begin,
-//                                    data::Object(false, data.gc.add(util::makeNil()))))
-//                 );
-//             ++begin;
-//             for (; begin != end; ++begin)
-//             {
-//                 // 順次oに再設定していく。
-//                 o = data::Object(
-//                     false, data.gc.add(
-//                         util::makeCons(*begin, o)));
-//             }
-//             pushList(data, o);
-//         }
-
-//         data.status.pop();
-//     }
-//     else if (data.lexm->getID() == lexeme::LexemeID::string ||
-//              data.lexm->getID() == lexeme::LexemeID::number ||
-//              data.lexm->getID() == lexeme::LexemeID::identifier ||
-//              data.lexm->getID() == lexeme::LexemeID::charactor ||
-//              data.lexm->getID() == lexeme::LexemeID::boolean)
-//     {
-//         // データスタックの頂上にあるvectorに追加する。
-//         data.compounds.top().push_back(
-//             data::Object(
-//                 false, data.gc.add(makePrimitiveFromLexeme(data.lexm))));
-//     }
-//     else if(isAbbrev(data.lexm))
-//     {
-//         // abbreviation は、結論としてはリストに展開される。carは常にabbreviationである
-//         // とすることで問題は無いので、作成したconsを、topに置くことで実現する。
-
-//         std::vector<data::Object> v;
-//         v.push_back(data::Object(false,
-//                                  data.gc.add(makePrimitiveFromLexeme(data.lexm))));
-
-//         data.compounds.push(v);
-
-//         // status stack に、 PS_ABBREVIATION と PS_INIT を積む。
-//         data.status.push(PS_ABBREVIATION);
-//         data.status.push(PS_INIT);
-//     }
-//     else if(data.lexm->getID() == lexeme::LexemeID::dot)
-//     {
-//         // .が来た場合で、topのvectorがemptyだったらどうしようもなくなるので終了。
-        
-//         if (data.compounds.top().empty())
-//         {
-//             data.status.push(PS_ERROR);
-//             data.error = "necessary one datum previous dot";
-//         }
-//         else
-//         {
-//             // この時点で、終わり方が確定したため、別のハンドラに任せる。
-//             // ただし、compoundの方は特に変化は必要が無いので、そちらはそのまま。
-//             data.status.pop();
-//             data.status.push(PS_END_DOT);
-//             data.status.push(PS_INIT);
-//         }
-//     }
-//     else
-//     {
-//         // 上記以外は許容しない。
-//         data.status.push(PS_ERROR);
-//     }
-
-//     return true;
-// }
-
-// void ListHandler::pushList(HandlerData& data, data::Object& o)
-// {
-//     if (!data.compounds.empty())
-//     {
-//         data.compounds.top().push_back(o);
-//     }
-//     else
-//     {
-//         data.stack.push(o);
-//     }
-// }
-
-// bool DotEndHandler::exec_(HandlerData& data)
-// {
-//     // .後の) を待つ部分のハンドラ。
-//     // このハンドラでは、) 以外が来た場合にはすべて構文エラーとなる。
-//     data.status.pop();
-//     if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis)
-//     {
-//         // stackの頂点とcompoundsのトップを取得する。
-//         std::vector<data::Object> v = data.compounds.top(); data.compounds.pop();
-//         // vectorをConsへと変換するには、次のようにして後ろからやっていく
-//         // 方式が一番面倒がない。
-//         // 1. cdrをstackのtop、carをvectorの末尾であるデータとしたconsを作成する。
-//         // 2. vectorの次のデータをcar、前のconsをcdrとしたconsを作成する。
-//         // 3. 先頭まで続ける。
-
-//         {
-//             // 後ろから前に向かっていく。
-//             std::vector<data::Object>::reverse_iterator begin = v.rbegin(),
-//                 end = v.rend();
-//             // ちょっと面倒すぎるなこれ。
-//             // cdrにcompoundsの末尾を、carにその前を設定する。
-//             data::Object o = data::Object(
-//                 false, data.gc.add(
-//                         util::makeCons(begin[1], begin[0]))
-//                 );
-//             begin += 2;
-//             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で正しく受け渡しができていれば問題は発生しない。
-//     }
-//     else
-//     {
-//         // 上記以外は許容しない。
-//         data.status.push(PS_ERROR);
-//     }
-
-//     return true;
-// }
-
-// // Abbreviation 処理のハンドリング。
-
-// bool AbbrevHandler::exec_(HandlerData& data)
-// {
-//     // abbreviationの場合、すでにPS_INITを事前に積んであるため、
-//     // 一つ分のdatumが来ていることが確定している。
-//     // すでにabbreviation分のObjectはcompoundのtopに積んであるため、
-//     // consを作成して、compoundかstackのtopに積むだけ。
-
-//     std::vector<data::Object> v = data.compounds.top(); data.compounds.pop();
-
-//     if (v.size() != 2)
-//     {
-//         data.status.push(PS_ERROR);
-//     }
-//     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], c)));
-//         if (!data.compounds.empty())
-//         {
-//             data.compounds.top().push_back(o);
-//         }
-//         else
-//         {
-//             data.stack.push(o);
-//         }
-//     }
-
-//     data.status.pop();
-//     data.chain = true;
-
-//     return true;
-// }
-
-// // syntax error のハンドリング
-
-// bool ErrorHandler::exec_(HandlerData& data)
-// {
-//     // 基本的にはエラーのハンドリングを行うだけ。
-//     // 一応発生した前後の位置と発生した lexeme くらいは表示したいかな。
-//     std::stringstream ss;
-//     ss << "syntax error:" << data.error;
-//     throw DatumException(ss.str());
-
-//     return true;
-// }
+#include "src/lexer/lexer_interface.h"
+#include "lib/binary_tree.h"
+#include "src/parser/datum_parser.h"
+#include "src/parser/datum_tree.h"
+#include "src/lexer/token.h"
+#include "src/parser/datum.h"
+#include "src/parser/syntax_error.h"
+#include "src/parser/parser_state.h"
+
+namespace lexer = utakata::lexer;
+namespace parser = utakata::parser;
+namespace akbn = akebono;
+namespace datum = utakata::datum;
+
+// 取得したtokenは、各datumの構築開始時に、指定tokenとして設定します。
+// Parseは、lexerが終了するまで停止することはありません。
+// 利用するlexerが設定されていない場合には、処理が不可能であるため、
+// 例外を送出します。
+// 各tokenをlexerより取得したとき、その時点でのparser内部の状態により、
+// 処理を行うakebono::functionを返却し、functorによる処理を行います。
+// 
+parser::DatumTree* parser::DatumParser::Parse(reader::EncodingReader* reader) {
+  if (use_lexer_.get() == NULL) {
+    return NULL;
+  }
+
+  akbn::smart_ptr<lexer::Token> token(use_lexer_->Lex(reader));
+  parser::DatumTree* parsed_tree = new parser::DatumTree();
+  akebono::scoped_ptr<parser::DatumTree> scoped_tree(parsed_tree);
+
+  while (!token.is_null() && token->type() != lexer::Token::kEOS) {
+    if (!ParseDetail(*token, parsed_tree)) {
+      return NULL;
+    }
+  }
+
+  scoped_tree.release();
+  return parsed_tree;
+}
+
+// 渡されたlexerCreatorから新規に生成したLexerを、内部で利用するLexerとして
+// 設定します。
+void parser::DatumParser::SetLexerWithCreator(
+    const lexer::ILexerCreator& creator) {
+  use_lexer_.reset(creator.Create());
+}
+
+// 渡されたtokenに基づいて、target_treeへの設定等を行います。
+// 内部における現在の処理状態は、parser::detail::ParserStateによって
+// 管理されます。
+// ParserStateは、次のParserStateを返却するため、必ず次のParserStateに
+// 切り替えられます。
+// ParserStateが、HasError() == trueである場合には、構文エラーと判定します。
+bool parser::DatumParser::ParseDetail(const lexer::Token& token,
+                                      parser::DatumTree* target_tree) {
+  // parser::detail::IParserState* next_state =
+  //     current_state_->GetNextState(token, target_tree);
+  // current_state_.reset(next_state);
+
+  // if (next_state->HasError()) {
+  //   syntax_error_ = next_state->GetError();
+  //   return false;
+  // }
+
+  // return true;
+  return false;
+}
index 1033b28..87d4bf0 100755 (executable)
@@ -21,7 +21,8 @@ class IDatumBase;
 };
 
 namespace lexer {
-class ILexerCreater;
+class ILexerCreator;
+class IPartOfLexer;
 };
 
 namespace reader {
@@ -31,6 +32,11 @@ class EncodingReader;
 namespace parser {
 
 class SyntaxError;
+class DatumTree;
+
+namespace detail {
+class IParserState;
+} // end of namespace detail
 
 // 渡されたreaderから、lexerに基づいてdatumを構築し、返却します。n
 // parse時に構文違反が発生したデータについては、GetSyntaxErrorから、
@@ -48,25 +54,38 @@ class DatumParser {
   // 呼出元は、scoped_ptr等を利用して返されたポインタを保持するべきです。
   // 内部にてなんらかのエラーが発生した場合、構文違反が発生します。
   // また、何らかのエラーが発生した場合、返り値はNULLが返却されます。
-  akebono::binary_tree<datum::IDatumBase>* Parse(reader::EncodingReader* reader);
+  parser::DatumTree* Parse(reader::EncodingReader* reader);
 
   // 渡されたILexerCreatorを用いて、利用するLexerを設定します。
-  void SetLexerWithCreator(const ILexerCreator& creator);
+  void SetLexerWithCreator(const lexer::ILexerCreator& creator);
 
   // 構文違反が発生した場合に限り、作成されたSyntaxErrorが新規に作成されて
   // 返却されます。
   // 構文違反が発生していない場合、常にis_nullがtrueを返すsmart_ptrを
   // 返却します。
-  const parser::SyntaxError& GetSyntaxError() const {
-    return *syntax_error_;
+  const akebono::smart_ptr<parser::SyntaxError>& GetSyntaxError() const {
+    return syntax_error_;
   }
 
+  // 現在構文エラー情報を保持しているかどうかを返却します。
+  bool HasSyntaxError() const {return syntax_error_.is_null();}
+
  private:
+
+  // Parseの内部詳細を実装する関数です。実際の解析はこの関数内で行われます。
+  // datumの解析時に構文異常などが発生した場合、falseを返却します。
+  bool ParseDetail(const lexer::Token& token, DatumTree* target_tree);
+
   // 内部で利用されるlexerを保存します。保存されるlexerは、set_lexer_creator
   // によって新しいLexerCreatorが設定される度に更新されます。
   akebono::scoped_ptr<lexer::IPartOfLexer> use_lexer_;
 
+  // 構文異常などが発生した場合に作成される、構文異常用のオブジェクトです。
   akebono::smart_ptr<parser::SyntaxError> syntax_error_;
+
+  // 現在のParserの内部表現を保有し、各状態における処理を行う
+  // インターフェースの実装を保持します。
+  akebono::scoped_ptr<parser::detail::IParserState> current_state_;
 };
 
 }
diff --git a/src/parser/datum_tree.cpp b/src/parser/datum_tree.cpp
new file mode 100644 (file)
index 0000000..e497383
--- /dev/null
@@ -0,0 +1,28 @@
+#include "src/parser/datum_tree.h"
+#include "src/parser/datum.h"
+
+namespace parser = utakata::parser;
+
+// 宣言のコメントを参照して下さい
+parser::DatumTree::Iterator parser::DatumTree::Begin() {
+  return inner_tree_.begin();
+}
+
+// 宣言のコメントを参照してください。
+parser::DatumTree::Iterator parser::DatumTree::End() {
+  return inner_tree_.end();
+}
+
+// 宣言のコメントを参照してください。
+parser::DatumTree::Iterator parser::DatumTree::SetLeft(
+    const parser::DatumTree::Iterator& target,
+    datum::Datum* data) {
+  return inner_tree_.set_left(target, akebono::smart_ptr<datum::Datum>(data));
+}
+
+// 宣言のコメントを参照してください。
+parser::DatumTree::Iterator parser::DatumTree::SetRight(
+    const parser::DatumTree::Iterator& target,
+    datum::Datum* data) {
+  return inner_tree_.set_right(target, akebono::smart_ptr<datum::Datum>(data));
+}
diff --git a/src/parser/datum_tree.h b/src/parser/datum_tree.h
new file mode 100644 (file)
index 0000000..142a0cb
--- /dev/null
@@ -0,0 +1,53 @@
+// datum::Datumの派生クラスを保持するbinary treeをラップしたクラスとして振る舞う
+// ためのクラスを提供します。
+// これは、typedefの隠蔽のために利用されます。
+// インターフェースとしては、内部のbinary treeにすべて委譲しています。
+#ifndef _UTAKATA_SRC_PARSER_DATUM_TREE_H_
+#define _UTAKATA_SRC_PARSER_DATUM_TREE_H_
+
+#include "lib/smart_ptr.h"
+#include "lib/binary_tree.h"
+
+namespace utakata {
+
+namespace datum {
+class Datum;
+}  // namespace datum
+
+namespace parser {
+
+// binary_tree<smart_ptr<datum::Datum> >を内部要素として保持するクラス
+// です。
+// 上記の型に対するインターフェースを提供するための補助インターフェー
+// スとして振舞います。
+class DatumTree {
+ public:
+  DatumTree() : inner_tree_() {}
+  virtual ~DatumTree() {}
+
+  // 内部型に対するtypedefを提供します。
+  typedef akebono::binary_tree<akebono::smart_ptr<datum::Datum> >::iterator
+  Iterator;
+
+  // binary_tree::beginのインターフェースとして振舞います。
+  Iterator Begin();
+
+  // binary_tree::endのインターフェースとして振舞います。
+  Iterator End();
+
+  // binary_tree::set_leftのインターフェースとして振舞います。
+  Iterator SetLeft(const Iterator& target, datum::Datum* data);
+
+  // binary_tree::set_rightのインターフェースとして振舞います。
+  Iterator SetRight(const Iterator& target, datum::Datum* data);
+
+ private:
+
+  // 内部で保持する、委譲のためのクラスです。
+  akebono::binary_tree<akebono::smart_ptr<datum::Datum> > inner_tree_;
+};
+
+}  // namespace parser
+}  // namespace utakata
+
+#endif /* _UTAKATA_SRC_PARSER_DATUM_TREE_H_ */
diff --git a/src/parser/parser.cpp.bk b/src/parser/parser.cpp.bk
deleted file mode 100755 (executable)
index c6d396a..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-#include <sstream>
-#include <stack>
-
-#include "parser.h"
-#include "lexeme.h"
-#include "lexeme_data.h"
-#include "lexer.h"
-#include "lexeme_id.h"
-#include "datum_id.h"
-#include "reader.h"
-#include "object.h"
-#include "gc.h"
-#include "primitive.h"
-#include "primitive_class.h"
-#include "primitive_util.h"
-#include "data_castor.h"
-
-using namespace utakata;
-using namespace utakata::parser;
-using namespace utakata::lexeme;
-using namespace utakata::interpreter;
-
-parser::DatumException::DatumException(std::string str) : str_()
-{
-    // エラーメッセージを定義する。
-    std::stringstream ss;
-    ss << "datum error ! -- message : [" << str << "]" << std::endl;
-    str_ = ss.str();
-}
-
-const char* parser::DatumException::what() const throw()
-{
-    return str_.c_str();
-}
-
-////////////////////////////
-// Parser Implementations //
-///////////////////////////
-
-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;
-    p.second.add(new ListHandler);
-    handler_.insert(p);
-
-    // .内用ハンドラの設定
-    p.first = PS_END_DOT;
-    p.second.add(new DotEndHandler);
-    handler_.insert(p);
-
-    // abbreviation 用ハンドラの設定
-    p.first = PS_ABBREVIATION;
-    p.second.add(new AbbrevHandler);
-    handler_.insert(p);
-
-    // error 用のハンドラの設定
-    p.first = PS_ERROR;
-    p.second.add(new ErrorHandler);
-    handler_.insert(p);
-}
-
-smart_ptr<data::Object> parser::Parser::parse(smart_ptr<reader::StreamReader>& strm,
-                                              gc::GarbageCollector& gc)
-{
-    HandlerData data(gc);
-    data.status.push(PS_INIT);
-
-    while(!data.status.empty()) {
-
-        if(data.status.top() != PS_ERROR)
-        {
-            if (data.chain)
-            {
-                data.chain = false;
-            }
-            else
-            {
-                data.lexm = lexer_->lex(strm);
-            }
-            
-            if(data.lexm.isNull() ||
-               data.lexm->getID() == lexeme::LexemeID::eos)
-            {
-                break;
-            }
-            // 基本的にすべてハンドラに任せる。
-            handler_[data.status.top()]->exec(data);
-        }
-        else
-        {
-            // ERROR だったら、強制的にハンドラを回してループから抜ける。
-            handler_[data.status.top()]->exec(data);
-        }
-    }
-
-    // stackのtopにはmainが殘ったままなので、data.stackのtopを追加してやる。
-    smart_ptr<data::Object> ret(new data::Object(data.stack.top()));
-    return ret;
-}
-
-bool parser::isAbbrev(smart_ptr<lexeme::ILexeme> l)
-{
-    // abbreviation かどうかを判別する。
-    switch(l->getID().toEnum())
-    {
-    case lexeme::LexemeID::BACKQUOTE:        return true;
-    case lexeme::LexemeID::QUOTE:            return true;
-    case lexeme::LexemeID::UNQUOTE:          return true;
-    case lexeme::LexemeID::UNQUOTESPLICING:  return true;
-    case lexeme::LexemeID::SYNTAX:           return true;
-    case lexeme::LexemeID::QUASISYNTAX:      return true;
-    case lexeme::LexemeID::UNSYNTAX:         return true;
-    case lexeme::LexemeID::UNSYNTAXSPLICING: return true;
-    default:
-        return false;
-    }
-}
-
-interpreter::IObject* parser::makePrimitiveFromLexeme(smart_ptr<lexeme::ILexeme> l)
-{
-    // 各lexemeに対応した固定lexemeを返す。
-    interpreter::IObject* o = NULL;
-    switch (l->getID().toEnum())
-    {
-    case lexeme::LexemeID::STRING:
-        return util::makeString(l->getData()->string->str);
-    case lexeme::LexemeID::CHARACTOR:
-        return util::makeCharactor(l->getData()->charactor->spec);
-    case lexeme::LexemeID::IDENTIFIER:
-        return util::makeSymbol(l->getData()->symbol->id);
-    case lexeme::LexemeID::BOOLEAN:
-        return util::makeBoolean(l->getData()->boolean->boolean);
-    case lexeme::LexemeID::NUMBER:
-    {
-        lexeme::NumberData& t = *(l->getData()->number);
-        return util::makeNumber(t.real, t.imagin, t.exact,
-                                t.radix);
-    }
-    case lexeme::LexemeID::BACKQUOTE:
-        return util::Abbrev<primitive::Quasiquote>::make();
-    case lexeme::LexemeID::QUOTE:
-        return util::Abbrev<primitive::Quote>::make();
-    case lexeme::LexemeID::UNQUOTE:
-        return util::Abbrev<primitive::Unquote>::make();
-    case lexeme::LexemeID::UNQUOTESPLICING:
-        return util::Abbrev<primitive::UnquoteSplicing>::make();
-    case lexeme::LexemeID::SYNTAX:
-        return util::Abbrev<primitive::Syntax>::make();
-    case lexeme::LexemeID::QUASISYNTAX:
-        return util::Abbrev<primitive::Quasisyntax>::make();
-    case lexeme::LexemeID::UNSYNTAX:
-        return util::Abbrev<primitive::Unsyntax>::make();
-    case lexeme::LexemeID::UNSYNTAXSPLICING:
-        return util::Abbrev<primitive::UnsyntaxSplicing>::make();
-    default:
-        break;
-    }
-
-    return o;
-}
-
-/////////////////////
-// parser handlers //
-/////////////////////
-
-bool InitHandler::exec_(HandlerData& data)
-{
-    data.status.pop();
-    // 初期状態の解釈処理を行う。
-    if(data.lexm->getID() == lexeme::LexemeID::openParenthesis)
-    {
-        // 開き括弧である場合、compoundsに新しくpushして返る。
-        data.compounds.push(std::vector<data::Object>());
-        data.status.push(PS_LIST);
-    }
-    else if(data.lexm->getID() == lexeme::LexemeID::string ||
-            data.lexm->getID() == lexeme::LexemeID::number ||
-            data.lexm->getID() == lexeme::LexemeID::identifier ||
-            data.lexm->getID() == lexeme::LexemeID::charactor ||
-            data.lexm->getID() == lexeme::LexemeID::boolean)
-    {
-        // それぞれの場合、単純にstackに各オブジェクトをpushする。
-
-        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))
-    {
-        // abbreviation である場合には、 全体をリストに展開するため、carまでは
-        // 設定された状態にする。
-        std::vector<data::Object> v;
-        v.push_back(data::Object(false,
-                                 data.gc.add(makePrimitiveFromLexeme(data.lexm))));
-
-        data.compounds.push(v);
-
-        // status stack に、 PS_ABBREVIATIONとPS_INITを積む。
-        data.status.push(PS_ABBREVIATION);
-        data.status.push(PS_INIT);
-    }
-    else
-    {
-        throw DatumException("datum の開始記号ではありません");
-    }
-
-    return true;
-}
-
-// List 内部処理のハンドリング
-
-bool ListHandler::exec_(HandlerData& data)
-{
-    // list の開始部分である場合。
-    if(data.lexm->getID() == lexeme::LexemeID::openParenthesis)
-    {
-        // 更にcompoundsに追加して積む。
-        data.compounds.push(std::vector<data::Object>());
-        data.status.push(PS_LIST);
-    }
-    else if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis)
-    {
-        // 原則として、閉括弧が来た時点で終了とするだけでよい。
-        // 現在のtopにあるcompoundsが、データであるとされているため、
-        // とりあえずtopにあるvectorをConsの繋がりに変換する。
-
-        std::vector<data::Object> v = data.compounds.top(); data.compounds.pop();
-        // vectorをConsへと変換するには、次のようにして後ろからやっていく
-        // 方式が一番面倒がない。
-        // 1. cdrをnil、carをvectorの末尾であるデータとしたconsを作成する。
-        // 2. vectorの次のデータをcar、前のconsをcdrとしたconsを作成する。
-        // 3. 先頭まで続ける。
-
-        if (v.size() == 0)
-        {
-            // サイズが0の場合には、nilを設定する。
-            data::Object o = data::Object(false,
-                                          data.gc.add(util::makeNil()));
-            pushList(data, o);
-        }
-        else
-        {
-            // 後ろから前に向かっていく。
-            std::vector<data::Object>::reverse_iterator begin = v.rbegin(),
-                end = v.rend();
-            // ちょっと面倒すぎるなこれ。
-            data::Object o = data::Object(
-                false, data.gc.add(
-                    util::makeCons(*begin,
-                                   data::Object(false, data.gc.add(util::makeNil()))))
-                );
-            ++begin;
-            for (; begin != end; ++begin)
-            {
-                // 順次oに再設定していく。
-                o = data::Object(
-                    false, data.gc.add(
-                        util::makeCons(*begin, o)));
-            }
-            pushList(data, o);
-        }
-
-        data.status.pop();
-    }
-    else if (data.lexm->getID() == lexeme::LexemeID::string ||
-             data.lexm->getID() == lexeme::LexemeID::number ||
-             data.lexm->getID() == lexeme::LexemeID::identifier ||
-             data.lexm->getID() == lexeme::LexemeID::charactor ||
-             data.lexm->getID() == lexeme::LexemeID::boolean)
-    {
-        // データスタックの頂上にあるvectorに追加する。
-        data.compounds.top().push_back(
-            data::Object(
-                false, data.gc.add(makePrimitiveFromLexeme(data.lexm))));
-    }
-    else if(isAbbrev(data.lexm))
-    {
-        // abbreviation は、結論としてはリストに展開される。carは常にabbreviationである
-        // とすることで問題は無いので、作成したconsを、topに置くことで実現する。
-
-        std::vector<data::Object> v;
-        v.push_back(data::Object(false,
-                                 data.gc.add(makePrimitiveFromLexeme(data.lexm))));
-
-        data.compounds.push(v);
-
-        // status stack に、 PS_ABBREVIATION と PS_INIT を積む。
-        data.status.push(PS_ABBREVIATION);
-        data.status.push(PS_INIT);
-    }
-    else if(data.lexm->getID() == lexeme::LexemeID::dot)
-    {
-        // .が来た場合で、topのvectorがemptyだったらどうしようもなくなるので終了。
-        
-        if (data.compounds.top().empty())
-        {
-            data.status.push(PS_ERROR);
-            data.error = "necessary one datum previous dot";
-        }
-        else
-        {
-            // この時点で、終わり方が確定したため、別のハンドラに任せる。
-            // ただし、compoundの方は特に変化は必要が無いので、そちらはそのまま。
-            data.status.pop();
-            data.status.push(PS_END_DOT);
-            data.status.push(PS_INIT);
-        }
-    }
-    else
-    {
-        // 上記以外は許容しない。
-        data.status.push(PS_ERROR);
-    }
-
-    return true;
-}
-
-void ListHandler::pushList(HandlerData& data, data::Object& o)
-{
-    if (!data.compounds.empty())
-    {
-        data.compounds.top().push_back(o);
-    }
-    else
-    {
-        data.stack.push(o);
-    }
-}
-
-bool DotEndHandler::exec_(HandlerData& data)
-{
-    // .後の) を待つ部分のハンドラ。
-    // このハンドラでは、) 以外が来た場合にはすべて構文エラーとなる。
-    data.status.pop();
-    if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis)
-    {
-        // stackの頂点とcompoundsのトップを取得する。
-        std::vector<data::Object> v = data.compounds.top(); data.compounds.pop();
-        // vectorをConsへと変換するには、次のようにして後ろからやっていく
-        // 方式が一番面倒がない。
-        // 1. cdrをstackのtop、carをvectorの末尾であるデータとしたconsを作成する。
-        // 2. vectorの次のデータをcar、前のconsをcdrとしたconsを作成する。
-        // 3. 先頭まで続ける。
-
-        {
-            // 後ろから前に向かっていく。
-            std::vector<data::Object>::reverse_iterator begin = v.rbegin(),
-                end = v.rend();
-            // ちょっと面倒すぎるなこれ。
-            // cdrにcompoundsの末尾を、carにその前を設定する。
-            data::Object o = data::Object(
-                false, data.gc.add(
-                        util::makeCons(begin[1], begin[0]))
-                );
-            begin += 2;
-            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で正しく受け渡しができていれば問題は発生しない。
-    }
-    else
-    {
-        // 上記以外は許容しない。
-        data.status.push(PS_ERROR);
-    }
-
-    return true;
-}
-
-// Abbreviation 処理のハンドリング。
-
-bool AbbrevHandler::exec_(HandlerData& data)
-{
-    // abbreviationの場合、すでにPS_INITを事前に積んであるため、
-    // 一つ分のdatumが来ていることが確定している。
-    // すでにabbreviation分のObjectはcompoundのtopに積んであるため、
-    // consを作成して、compoundかstackのtopに積むだけ。
-
-    std::vector<data::Object> v = data.compounds.top(); data.compounds.pop();
-
-    if (v.size() != 2)
-    {
-        data.status.push(PS_ERROR);
-    }
-    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], c)));
-        if (!data.compounds.empty())
-        {
-            data.compounds.top().push_back(o);
-        }
-        else
-        {
-            data.stack.push(o);
-        }
-    }
-
-    data.status.pop();
-    data.chain = true;
-
-    return true;
-}
-
-// syntax error のハンドリング
-
-bool ErrorHandler::exec_(HandlerData& data)
-{
-    // 基本的にはエラーのハンドリングを行うだけ。
-    // 一応発生した前後の位置と発生した lexeme くらいは表示したいかな。
-    std::stringstream ss;
-    ss << "syntax error:" << data.error;
-    throw DatumException(ss.str());
-
-    return true;
-}
diff --git a/src/parser/parser.h b/src/parser/parser.h
deleted file mode 100755 (executable)
index 50d1204..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef _PARSER_H_
-#define _PARSER_H_
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "smart_ptr.h"
-#include "parser_handler.h"
-#include "parser_status.h"
-
-namespace utakata {
-
-    namespace syntax {
-        class DatumID;
-    };
-
-    namespace interpreter {
-        class Object;
-        class IObject;
-    };
-
-    namespace lexer {
-        class Lexer;
-    };
-
-    namespace reader {
-        class StreamReader;
-    };
-
-    namespace gc {
-        class GarbageCollector;
-    };
-
-    namespace parser {
-    
-        class DatumException : public std::exception
-        {
-        public:
-            DatumException(std::string str);
-            virtual ~DatumException() throw() {}
-            const char* what() const throw();
-
-        private:
-
-            std::string str_;
-        };
-
-        class Parser
-        {
-            // lexerを受け取り、lexerが保持する全体の解析を行いつつ、
-            // 実行を行う。
-            // 実行は、基本的に全体を読み込み、全体を保持した状態で行う。
-            
-        public:
-            
-            Parser(smart_ptr<lexer::Lexer> l);
-            virtual ~Parser() {}
-
-            // 受け取ったlexerからの字句の取得を行い、解析を行なう。
-            // 成功した場合には、datum一つを表す状態を返す。
-            // 致命的なエラーが発生した場合には例外を返す。
-            smart_ptr<data::Object> parse(smart_ptr<reader::StreamReader>& strm,
-                                          gc::GarbageCollector& gc);
-
-        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);
-
-        // 渡されたlexemeに対応する各lexeme datumを生成して返す。
-        interpreter::IObject* makePrimitiveFromLexeme(smart_ptr<lexeme::ILexeme> l);
-
-        // 各ハンドラの定義。
-
-        class InitHandler : public IParserHandler
-        {
-            // PS_INITに対応するハンドラ
-        public:
-            InitHandler() {}
-            virtual ~InitHandler() {}
-
-        private:
-
-            bool exec_(HandlerData &data);
-
-        };
-
-        // <list>に対応するものだけは、carとcdrでハンドラが分離している。
-        class ListHandler : public IParserHandler
-        {
-            // PS_LIST_CARである間に対応するハンドラ
-        public:
-            ListHandler() {}
-            virtual ~ListHandler() {}
-
-        private:
-
-            bool exec_(HandlerData& data);
-
-            // 現在のハンドラデータの内容から、pushすべきスタックを
-            // 決定してpushする。
-            void pushList(HandlerData& data, data::Object& o);
-
-        };
-
-        // .後のdatumに対応するためのハンドラ
-        class DotEndHandler : public IParserHandler
-        {
-            // PS_END_DOTに対応するハンドラ。
-        public:
-            DotEndHandler() {}
-            virtual ~DotEndHandler() {}
-
-        private:
-
-            bool exec_(HandlerData& data);
-
-        };
-
-
-        class AbbrevHandler : public IParserHandler
-        {
-            // PS_ABBREVIATIONに対応するハンドラ
-        public:
-            AbbrevHandler() {}
-            virtual ~AbbrevHandler() {}
-
-        private:
-
-            bool exec_(HandlerData& data);
-
-        };
-
-        class ErrorHandler : public IParserHandler
-        {
-            // PS_ERRORをハンドリングする。実際にはエラーを通告する
-            // のみ。
-        public:
-            ErrorHandler() {}
-            virtual ~ErrorHandler() {}
-            
-        private:
-
-            bool exec_(HandlerData& data);
-
-        };
-
-    };
-
-};
-
-#endif /* _PARSER_h_ */
diff --git a/src/parser/parser_handler.cpp.bk b/src/parser/parser_handler.cpp.bk
deleted file mode 100755 (executable)
index 5a2efc6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "parser_handler.h"
-#include "object.h"
-
-
-using namespace std;
-using namespace utakata::parser;
-
-bool IParserHandler::exec(HandlerData& data)
-{
-    return exec_(data);
-}
-
diff --git a/src/parser/parser_handler.h b/src/parser/parser_handler.h
deleted file mode 100755 (executable)
index e260748..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef _PARSER_HANDLER_H_
-#define _PARSER_HANDLER_H_
-
-#include "smart_ptr.h"
-#include <string>
-#include <stack>
-#include <vector>
-#include "parser_status.h"
-
-namespace utakata {
-
-    namespace lexeme {
-        class ILexeme;
-    };
-
-    namespace data {
-        class Object;
-    };
-
-    namespace gc {
-        class GarbageCollector;
-    };
-
-    namespace parser {
-
-        struct HandlerData
-        {
-            HandlerData(gc::GarbageCollector& g) : gc(g), chain(false) {}
-
-            smart_ptr<lexeme::ILexeme> lexm;
-            std::stack<data::Object> stack;
-            std::stack<std::vector<data::Object> > compounds;
-            gc::GarbageCollector& gc;
-            std::stack<PARSERSTATUS> status;
-            std::string error;   // syntax errorなどを通知する。
-            bool chain;          // 現在のlexemeを維持したまま次のstatusに基づいた処理を行う。
-        };
-        
-        class IParserHandler
-        {
-        public:
-            
-            IParserHandler() {}
-            virtual ~IParserHandler() {}
-
-            // 構文木のスタックとstatusのスタックを元に、Treeを
-            // 構築する。
-            bool exec(HandlerData& data);
-
-        private:
-
-            // 実際に起動される関数。
-            // 処理が行われた場合にはtrue、行われなかった場合にはfalseを
-            // 返すこと。
-            virtual bool exec_(HandlerData& data) = 0;
-
-        };
-
-    };
-
-};
-
-#endif /* _PARSER_HANDLER_H_ */
diff --git a/src/parser/parser_state.h b/src/parser/parser_state.h
new file mode 100755 (executable)
index 0000000..4553a93
--- /dev/null
@@ -0,0 +1,54 @@
+// DatumParserにおいて、内部のParser状態を表現するためのインターフェース
+// を提供します。
+#ifndef _UTAKATA_SRC_PARSER_PARSER_STATE_H_
+#define _UTAKATA_SRC_PARSER_PARSER_STATE_H_
+
+#include "lib/smart_ptr.h"
+#include "lib/binary_tree.h"
+
+namespace utakata {
+
+namespace lexer {
+class Token;
+}  // namespace lexer
+
+namespace datum {
+class IDatumBase;
+} // end of namespace datum
+
+namespace parser {
+
+// forward declare
+class SyntaxError;
+class DatumTree;
+
+namespace detail {
+
+// DatumParserの内部で作成/保持される、関数オブジェクト的に現在の状態を
+// 取得するためのインターフェースです。
+// IParserState派生クラスは、現在の派生型に対して、処理可能であるtoken
+// などを内部で判断し、構文違反なども検出します。
+class IParserState {
+public:
+  virtual ~IParserState() {}
+
+  // 渡されたtokenが、現在の状態に対して正常である場合に、次の
+  // ParserStateを返却します。
+  // tokenの取得時点で、特定のdatumの構造が確定された場合、target_tree
+  // の更新を行います。
+  virtual IParserState* GetNextState(const lexer::Token& token,
+                             DatumTree* target_tree) = 0;
+
+  // 構文エラーが発生した場合、trueを返却します。
+  virtual bool HasError() const = 0;
+
+  // HasErrorがtrueを返却した場合にのみ、有効であるSyntaxErrorを返却
+  // します。
+  virtual akebono::smart_ptr<parser::SyntaxError> GetError() = 0;
+};
+
+} // end of namespace detail
+} // end of namespace parser
+} // end of namespace utakata
+
+#endif /* _UTAKATA_SRC_PARSER_PARSER_STATE_H_ */
diff --git a/src/parser/parser_status.h b/src/parser/parser_status.h
deleted file mode 100755 (executable)
index 607f9a7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _PARSER_STATUS_H_
-#define _PARSER_STATUS_H_
-
-namespace utakata {
-    namespace parser {
-        enum PARSERSTATUS {
-            PS_INIT                = 0,  /* 初期時点 */
-            PS_DATUM               = 1,  /* detumであるかどうか */
-            PS_LEXEME_DATUM        = 2,  /* lexeme_detumのどれかであるか */
-            PS_LIST                = 4,  /* リストdatumの処理。*/
-            PS_ABBREVIATION        = 7,  // abbrev syntaxの後。
-            PS_VECTOR_START        = 15, /* #( */
-            PS_VECTOR_END          = 16, /* #(と対応した) */
-            PS_BYTEVECTOR_START    = 17, /* #vu8( */
-            PS_BYTEVECTOR_END      = 18, /* #vu8(と対応した) */
-            PS_ERROR,                    // 構文異常が発生した場合に設定される。
-                                         // これが設定されている場合、lexmの読み出しは進まず、
-                                         // その時点で終了することになる。
-            PS_END_DOT,                 // listの終了時点を表す。)以外は許容されない。
-        };
-    };
-};
-
-#endif /* _PARSER_STATUS_H_ */
diff --git a/src/parser/syntax_error.cpp b/src/parser/syntax_error.cpp
new file mode 100755 (executable)
index 0000000..0343344
--- /dev/null
@@ -0,0 +1,18 @@
+#include "src/parser/syntax_error.h"
+#include "src/parser/datum_base.h"
+#include "src/lexer/token.h"
+
+namespace parser = utakata::parser;
+namespace datum = utakata::datum;
+namespace lexer = utakata::lexer;
+
+// 与えられたdatumが保持しているTokenの位置をエラー情報として
+// 保持します。与えられたdatumはエラー発生時点のdatumであるはずと判断
+// しています。
+parser::SyntaxError::SyntaxError(const datum::Datum& datum,
+                                 akebono::function<std::string()> functor)
+    : error_line_(0), error_column_(0), error_message_(functor()) {
+  const lexer::Token& error_token = datum.token();
+  // error_line_ = error_token.line();
+  // error_column_ = error_token.column();
+}
diff --git a/src/parser/syntax_error.h b/src/parser/syntax_error.h
new file mode 100755 (executable)
index 0000000..efd87a0
--- /dev/null
@@ -0,0 +1,45 @@
+// Parserにおいて発生した構文エラーを格納するクラスです。
+// DatumParserにおいて、エラーが発生した場合にのみ作成され、返却されます。
+// 構文違反が発生したdatumをコピーして保持しています。
+#ifndef _UTAKATA_SRC_PARSER_SYNTAX_ERROR_H_
+#define _UTAKATA_SRC_PARSER_SYNTAX_ERROR_H_
+
+#include "lib/function.h"
+#include <string>
+
+namespace utakata {
+namespace datum {
+class Datum;
+} // end of namespace datum
+
+namespace parser {
+
+// 渡されたdatumと、エラーメッセージを返却するfunctorから、
+// 構文エラー情報を作成します。
+// functorは、akebono::functionによって表現されているため、シグネチャに
+// 該当する関数を設定することができます。
+class SyntaxError {
+public:
+  // datumとfunctorから、構文エラーを作成します。
+  SyntaxError(const datum::Datum& datum,
+              akebono::function<std::string()> functor);
+  virtual ~SyntaxError() {}
+
+  int error_line() const {return error_line_;}
+
+  int error_column() const {return error_column_;}
+
+  std::string error_message() const {return error_message_;}
+
+ private:
+
+  // 各エラー情報です。それぞれ、コンストラクタで初期化が行われた
+  // 後、変更は行われません。
+  int error_line_;
+  int error_column_;
+  std::string error_message_;
+};
+} // end of namespace parser
+} // end of namespace utakata
+
+#endif /* _UTAKATA_SRC_PARSER_SYNTAX_ERROR_H_ */
diff --git a/test/datum_tree_test.cpp b/test/datum_tree_test.cpp
new file mode 100755 (executable)
index 0000000..9104722
--- /dev/null
@@ -0,0 +1,39 @@
+#include <iostream>
+#include <test/gtest/gtest.h>
+#include "lib/smart_ptr.h"
+#include "src/parser/datum.h"
+#include "src/parser/datum_tree.h"
+#include "src/object.h"
+#include "src/unicode.h"
+
+namespace data = utakata::data;
+namespace interpreter = utakata::interpreter;
+namespace unicode = utakata::unicode;
+namespace datum = utakata::datum;
+namespace parser = utakata::parser;
+
+using namespace akebono;
+
+TEST(DatumTreeTest, TreeValid) {
+  parser::DatumTree tree;
+  parser::DatumTree::Iterator it = tree.Begin();
+
+  datum::String* tmp = new datum::String(lexer::Token(unicode::Convert("hoge")),
+                                         unicode::Convert("huga"));
+  tree.SetLeft(it, tmp);
+  it = tree.SetRight(it, new datum::Cons(lexer::Token(unicode::Convert("("))));
+  tree.SetLeft(it, datum::Symbol(lexer::Token(unicode::Convert("test")),
+                                 unicode::Convert("+")));
+
+  it = tree.Begin(); ++it;
+  EXPECT_EQ(*it->type(), datum::kString); ++it;
+  EXPECT_EQ(*it->type(), datum::kCons); ++it;
+  EXPECT_EQ(*it->type(), datum::kSymbol); ++it;
+}
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
+
+
index 93e7f89..d76a2f7 100755 (executable)
@@ -1,24 +1,29 @@
-#include <iostream>
-#include <sstream>
 #include <string>
-#include <functional>
+#include "gtest/gtest.h"
 
 #include "lib/textarrayformat.h"
 #include "src/unicode.h"
 #include "src/parser/datum_parser.h"
-#include "src/lexer/lexer.h"
+#include "src/parser/syntax_error.h"
+#include "src/lexer/scheme_lexer.h"
 
 #include "lib/binary_tree.h"
+#include "lib/scoped_ptr.h"
+#include "lib/smart_ptr.h"
 #include "src/utf8_transcoder.h"
 #include "src/string_reader.h"
+#include "src/encoding_reader.h"
+#include "src/parser/datum_base.h"
 
 namespace textarrayformat = utility::textarrayformat;
 namespace lexer = utakata::lexer;
 namespace unicode = utakata::unicode;
 namespace reader = utakata::reader;
 namespace transcoder = utakata::transcoder;
+namespace datum = utakata::datum;
+namespace parser = utakata::parser;
 
-class SchemeLexerTest : public ::testing::Test {
+class ParserTest : public ::testing::Test {
  protected:
   virtual void SetUp() {
     gen.reset(new textarrayformat::TextArrayGenerator("========="));
@@ -50,112 +55,116 @@ TEST_F(ParserTest, LexemeToDatum) {
   parser::DatumParser parser;
   parser.SetLexerWithCreator(lexer::SchemeLexerCreator());
 
-  akebono::scoped_ptr<akebono::binary_tree<datum::IDatumBase> > tree(
-      parser.Parse(&reader));
+  akebono::scoped_ptr<parser::DatumTree> tree(parser.Parse(&reader));
 
-  akebono::binary_tree<datum::Datum>::iterator it = tree->begin();
-  
-  EXPECT_EQ(it->type(), datum::Datum::kCons);
+  parser::DatumTree::iterator it = tree->begin();
+
+  EXPECT_EQ((*it)->type(), datum::kCons);
   ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->ToString(), unicode::Convert("define"));
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("define")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->ToString() == unicode::Convert("define"));
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("define")); ++it;
 
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->ToString(), unicode::Convert("fact"));
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("fact")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->ToString() == unicode::Convert("fact"));
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("fact")); ++it;
 
   // (lambda
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("lambda")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("lambda")); ++it;
 
   // (n)
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("n")); ++it;
 
   // (if
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("if")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("if")); ++it;
 
   // (= n 0)
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("=")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("=")); ++it;
 
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("n")); ++it;
 
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kNumber);
-  EXPECT_EQ(it->ToString(), unicode::Convert("0")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kNumber);
+  EXPECT_TRUE((*it)->ToString() == unicode::Convert("0")); ++it;
 
   // 1
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kNumber);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("1")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kNumber);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("1")); ++it;
 
   // (* n
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("*")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("*")); ++it;
 
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("n")); ++it;
 
   // (fact
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("fact")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("fact")); ++it;
 
   // (- n
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("-")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("-")); ++it;
 
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("n")); ++it;
 
   // '1
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("quote")); ++it;
-
-  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
-  EXPECT_EQ(it->type(), datum::Datum::kNumber);
-  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("1")); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kSymbol);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("quote")); ++it;
+
+  EXPECT_EQ((*it)->type(), datum::kCons); ++it;
+  EXPECT_EQ((*it)->type(), datum::kNumber);
+  EXPECT_TRUE((*it)->GetSymbolName() == unicode::Convert("1")); ++it;
 }
 
 // 例外となる構文についてのエラーをチェックします。
 TEST_F(ParserTest, GetCondition) {
-  textarrayformat::TextArrayReader textarray(*gen);
+      textarrayformat::TextArrayReader textarray(*gen);
 
-  reader::StringReader sr(textarray.GetBlockAt(0));
-  reader::EncodingReader reader(&sr, new transcoder::UTF8Transcoder);
+      reader::StringReader sr(textarray.GetBlockAt(0));
+      reader::EncodingReader reader(&sr, new transcoder::UTF8Transcoder);
   
-  lexer::SchemeLexer lexer;
-  parser::DatumParser parser;
-  parser.SetLexerWithCreator(lexer::SchemeLexerCreator());
+      lexer::SchemeLexer lexer;
+      parser::DatumParser parser;
+      parser.SetLexerWithCreator(lexer::SchemeLexerCreator());
+
+      akebono::scoped_ptr<parser::DatumTree> tree(parser.Parse(&reader));
 
-  akebono::scoped_ptr<akebono::binary_tree<datum::IDatumBase> > tree(
-      parser.Parse(&reader));
+      EXPECT_TRUE(tree.get() == NULL);
 
-  EXPECT_TRUE(tree.is_null());
+      EXPECT_TRUE(parser.HasSyntaxError());
+      akebono::smart_ptr<parser::SyntaxError> error = parser.GetSyntaxError();
 
+      // EXPECT_EQ(error.error_line(), 1);
+      // EXPECT_EQ(error.error_column(), 1);
+      // EXPECT_EQ(error.error_message(), "not found match parenthesis");
                      }
 
 int main(int argc, char** argv) {