OSDN Git Service

fd877fa953358cc4ac181fd73cc81464bf456457
[simplecms/utakata.git] / refactor_target / tree.cpp
1 #include <iostream>
2
3 #include <assert.h>
4 #include <exception>
5
6 #include "tree.h"
7 #include <stack>
8
9 #include "unicode.h"
10 #include "literal_data.h"
11 #include "literal.h"
12 #include "datum_id.h"
13
14 using namespace utakata;
15 using namespace utakata::literal;
16 using namespace utakata::unicode;
17 using namespace utakata::syntax;
18
19 // 原則としてそれぞれ単純に呼びだされるのみ。
20
21 struct Tree::TreeNode
22 {
23     TreeNode (node_pair p) : list(), datum (p) {}
24
25     std::vector<smart_ptr<TreeNode> > list;
26
27     // datumの型と値の両方を保持する。
28     Tree::node_pair datum;
29 };
30
31 ////////////////////////////
32 // syntax::Tree::iterator //
33 ////////////////////////////
34
35 syntax::Tree::iterator::iterator () : current_()
36 {
37 }
38
39 syntax::Tree::iterator::iterator (const Tree::iterator& i)
40 {
41     swap (i);
42 }
43
44 syntax::Tree::iterator& syntax::Tree::iterator::operator=(const Tree::iterator& rh)
45 {
46     iterator it (rh);
47     swap (it);
48     return *this;
49 }
50
51 void syntax::Tree::iterator::swap (const Tree::iterator& t)
52 {
53     current_ = t.current_;
54 }
55
56 Tree::iterator& Tree::iterator::operator++ ()
57 {
58     // car,cdr をそれぞれ巡回する。 car,cdr それぞれに移動する場合には、
59     // it を元の tree に渡して取得する。
60     // 巡回の順序は次の通りとする。
61     // cons -> cdr に繋がっている cons
62     // ただし、 cdr に繋がっている cons が literal の場合、以降は進むことが
63     // 無く、また list として判定されることはない。
64
65     ++current_;
66     return *this;
67 }
68
69 std::pair<DatumID, smart_ptr<literal::Literal> >& Tree::iterator::operator*()
70 {
71     // 現在の current_が指す node のリテラルを返す。
72     return (*current_)->datum;
73 }
74
75 std::pair<DatumID, smart_ptr<literal::Literal> >* Tree::iterator::operator->()
76 {
77     // 現在の current_が指す node のリテラルを返す。
78     return &((*current_)->datum);
79 }
80
81 bool Tree::iterator::operator==(const Tree::iterator& rh)
82 {
83     // node_が指す先が同一かどうかを返す。
84     // 但し、自身か相手のいずれかが nil である場合だけは例外的に、単純に DatumID のみの
85     // 比較になる。
86     return current_ == rh.current_;
87 }
88
89 //////////////////
90 // syntax::Tree //
91 //////////////////
92
93 Tree::Tree () : node_()
94 {
95     // 初期値を設定する。
96     // smart_ptr<TreeNode> p(new TreeNode(makeNilList()));
97     // 最後尾には常にnilがいることにする。
98 }
99
100 Tree::iterator Tree::begin ()
101 {
102     // 開始点を示すデータを返す。
103     iterator it;
104     it.current_ = node_.begin();
105     return it;
106 }
107
108 Tree::iterator Tree::end ()
109 {
110     // 終了地点を示す部分を返す。
111     iterator it;
112     it.current_ = node_.end();
113     return it;
114 }
115
116 void Tree::push_back(node_pair datum)
117 {
118     // 渡されたdatumを、現在保持しているデータ型に追加する。
119     smart_ptr<TreeNode> p(new TreeNode(datum));
120     node_.insert(node_.end(), p);
121 }
122
123 void Tree::push_back(Tree::iterator it, Tree::iterator it2,
124                      node_pair datum)
125 {
126     // itとit2までを、datumで設定されたdatumidであるcompound datum
127     // に格納して追加する。
128     smart_ptr<TreeNode> p(new TreeNode(datum));
129     p->list.insert(p->list.end(), it.current_, it2.current_);
130     node_.insert(node_.end(), p);
131 }
132
133 Tree::iterator Tree::in_compound_begin(Tree::iterator it)
134 {
135     // itがcompound datumである場合に、compound datumの内部リストを返す。
136     if (isCompoundDatum(it))
137     {
138         iterator ret;
139         ret.current_ = (*it.current_)->list.begin();
140         return ret;
141     }
142     else
143     {
144         // 違う場合には、endを返すことにする。
145         return end();
146     }
147 }
148
149 Tree::iterator Tree::in_compound_end(Tree::iterator it)
150 {
151     // itがcompound datumである場合に、compound datumの内部リストを返す。
152     if (isCompoundDatum(it))
153     {
154         iterator ret;
155         ret.current_ = (*it.current_)->list.end();
156         return ret;
157     }
158     else
159     {
160         // 違う場合には、endを返すことにする。
161         return end();
162     }
163 }
164
165 //////////////////////
166 // helper functions //
167 //////////////////////
168
169 bool syntax::isCompoundDatum(Tree::iterator it)
170 {
171     if (it->first == syntax::DatumID::list ||
172         it->first == syntax::DatumID::vector ||
173         it->first == syntax::DatumID::byteVector)
174     {
175         return true;
176     }
177     else
178     {
179         return false;
180     }
181 }
182
183 std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeCompoundDatum (
184     DatumID id)
185 {
186     // datum_id が list である node_pair を返す。
187     return std::pair<DatumID, smart_ptr<literal::Literal> >(id, smart_ptr<literal::Literal>());
188 }
189
190 std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeNilList ()
191 {
192     // datum_id が nil である node_pair を返す。
193     return std::pair<DatumID, smart_ptr<literal::Literal> >(
194         DatumID(DatumID::nil), smart_ptr<literal::Literal>());
195 }
196
197 std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeLexemeDatum (smart_ptr<literal::Literal> l,
198     DatumID id)
199 {
200     // datum_id が各 lexeme であり、 literal として l を持つ
201     // datum を返す。
202     return std::pair<DatumID, smart_ptr<literal::Literal> >(
203         id, l);
204 }
205
206 std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeAbbreviation (smart_ptr<literal::Literal> l)
207 {
208     // datum_id が literal であり、 literal として l を持つ
209     // datum を返す。
210     return std::pair<DatumID, smart_ptr<literal::Literal> >(
211         DatumID (DatumID::abbreviations), l);
212 }
213