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
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}
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
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
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
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)
## 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
/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
## ----------- ##
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
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.
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
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
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.
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
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
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. */
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. */
CONFIG_COMMANDS =
$ ./config.status
-on c2007
+on vaio_z
config.status:778: creating Makefile
config.status:778: creating Rakefile
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
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'
## 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'
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}'
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'
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'
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
S["am__include"]="include"
S["DEPDIR"]=".deps"
S["OBJEXT"]="o"
-S["EXEEXT"]=".exe"
+S["EXEEXT"]=""
S["ac_ct_CXX"]="g++"
S["CPPFLAGS"]=""
S["LDFLAGS"]=""
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"
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}"
// 実際にアクセスすることはできません。
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_;
// 同じ親に接続されている前後のnodeを指します。
// ただし、二分木の場合、左ノードの場合はnext_sibling_に右ノードが、
// 右ノードの場合はpref_sibling_に左ノードが設定され、
- // それぞれprev/nextはNULLが設定されます。
+ // それぞれprev/nextは0が設定されます。
node<T>* next_sibling_;
node<T>* prev_sibling_;
return true;
}
- while (now_target->next_sibling_ == NULL) {
+ while (now_target->next_sibling_ == 0) {
if (!now_target->parent_) {
return false;
}
}
// 渡されたtargetから、次に進むべきデータを返します。
- // has_nextがfalseを返却する場合、NULLが返却されます。
+ // has_nextがfalseを返却する場合、0が返却されます。
node<T>* next(node<T>* target) {
if (target->left_) {
return target->left_;
}
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;
}
}
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_() {}
// 番兵として機能する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() {
// 関数ポインタの場合に該当する、関数ポインタの実行、及び開放関数を
// 保持するための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();
}
// 関数オブジェクトの場合に該当する関数オブジェクトの実行、及び開放関数を
// 保持するための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)();
}
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>
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;
};
// 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;
// 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;
// iterator型を保持していない場合、こちらが適用されます。
template <typename C>
static no test(...);
+
+ public:
+ // test<T>(0)は、test()関数に型適用を施して呼び出し、結果の型
+ // を取得する構文です。
+ static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
// 引数が指定されない場合、NULLがデフォルト引数となります。
void reset(T* p = NULL) {
if (p != obj_) {
- if (sizeof(T) > 0) {
- delete obj_;
- }
+ delete obj_;
obj_ = p;
}
}
#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_;
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_;
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 {
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();
}
// 宣言のコメントを参照してください。
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();
}
// 宣言のコメントを参照してください。
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;
+}
+
class UniChar;
}
+namespace lexer {
+class Token;
+} // namespace lexer
+
namespace datum {
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() {}
// このオブジェクトの文字列表現を返します。
// 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() {}
// このオブジェクトの文字列表現を返します。
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() {}
// このオブジェクトの文字列表現を返します。
// そのように変更される場合があります。
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() {}
// このオブジェクトの文字列表現を返します。
// 真偽値を直接保存します。
bool boolean_value_;
-
- // 真偽値の文字列をそのまま保存します。
- akebono::scoped_ptr<unicode::UniString> original_string_;
};
// datum syntaxにおける<number>を表現します。
// そのように変更される場合があります。
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() {}
// このオブジェクトの文字列表現を返します。
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() {}
// このオブジェクトの文字列表現を返します。
// しているのみとなります。
class Vector : public datum::Datum {
public:
- explicit Vector(const lexer::Token& token) : Datum(token) {}
+ explicit Vector(const lexer::Token& token);
virtual ~Vector() {}
// このオブジェクトの文字列表現を返します。
// 行いません。
class Bytevector : public datum::Datum {
public:
- explicit Bytevector(const lexer::Token& token)
- : Datum(token), datum_list_() {}
+ explicit Bytevector(const lexer::Token& token);
virtual ~Bytevector() {}
// このオブジェクトの文字列表現を返します。
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;
}
// 内部に内包しているDatumのリストとなります。
// 内部に内包することが可能なのは、任意のdatumであるため、この時点
// では一意に確定はしません。
- std::vector<akebono::smart_ptr<Datum> > datum_list_;
+ std::vector<akebono::smart_ptr<IDatumBase> > datum_list_;
};
}
+#include "src/lexer/token.h"
#include "src/exception_macro.h"
#include "src/exception_std.h"
#include "src/parser/datum.h"
namespace datum = utakata::datum;
namespace unicode = utakata::unicode;
namespace exception = utakata::exception;
+namespace lexer = utakata::lexer;
// 宣言のコメントを参照して下さい。
bool datum::IDatumBase::GetBoolean() 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`"));
}
: token_(new lexer::Token(token)) {}
// 宣言のコメントを参照して下さい
-const lexer::Token& datum::Datum::GetBaseToken() const {
+const lexer::Token& datum::Datum::token() const {
return *token_;
}
class UniChar;
}
+namespace lexer {
+class Token;
+} // namespace lexer
+
namespace interpreter {
class Environment;
} // end of namespace interpreter
virtual datum::DatumType type() const = 0;
// datumが構築された時に元となったTokenを返却します。
- virtual const lexer::Token& GetBaseToken() const = 0;
+ virtual const lexer::Token& token() const = 0;
};
virtual ~Datum() {}
// datumが構築された時に元となったTokenを返却します。
- virtual const lexer::Token& GetBaseToken() const;
+ virtual const lexer::Token& token() const;
private:
-// #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;
+}
};
namespace lexer {
-class ILexerCreater;
+class ILexerCreator;
+class IPartOfLexer;
};
namespace reader {
namespace parser {
class SyntaxError;
+class DatumTree;
+
+namespace detail {
+class IParserState;
+} // end of namespace detail
// 渡されたreaderから、lexerに基づいてdatumを構築し、返却します。n
// parse時に構文違反が発生したデータについては、GetSyntaxErrorから、
// 呼出元は、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_;
};
}
--- /dev/null
+#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));
+}
--- /dev/null
+// 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_ */
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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_ */
+++ /dev/null
-#include "parser_handler.h"
-#include "object.h"
-
-
-using namespace std;
-using namespace utakata::parser;
-
-bool IParserHandler::exec(HandlerData& data)
-{
- return exec_(data);
-}
-
+++ /dev/null
-#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_ */
--- /dev/null
+// 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_ */
+++ /dev/null
-#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_ */
--- /dev/null
+#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();
+}
--- /dev/null
+// 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_ */
--- /dev/null
+#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();
+}
+
+
-#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("========="));
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) {