annotate boost-spirit/CALC/AST-value/calc.cpp @ 0:db40c85cad7a default tip

upload sample source
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Mon, 09 May 2011 03:11:59 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 #include <boost/spirit/core.hpp>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 #include <boost/spirit/utility/confix.hpp>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 #include <boost/spirit/tree/ast.hpp>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 #include <boost/spirit/utility/escape_char.hpp>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 #include <boost/spirit/iterator/position_iterator.hpp>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 #include <boost/spirit/iterator/file_iterator.hpp>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 #include <boost/spirit/utility/functor_parser.hpp>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 #include <iostream>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #include <map>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #include <string>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 #include <cassert>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 #include <algorithm>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 using namespace std;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 using namespace boost::spirit;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 typedef file_iterator<> iterator_t;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 typedef node_val_data_factory<int> factory_t;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 typedef tree_match<iterator_t, factory_t> tree_match_t;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 typedef tree_match_t::tree_iterator tree_iter_t;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 map<string, int> values; // 変数テーブル
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 struct error_parser {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 typedef nil_t result_t; // パーサーの結果型(nil_t)
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 error_parser(char const *msg)
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 : msg_(msg)
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 template <typename ScannerT>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 int operator()(ScannerT const &scan, result_t &result) const
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 // 終わりまで来たら-1を返す
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 if (scan.at_end()) {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 return -1;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 cout << msg_ << endl;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 // 解釈した「長さ」を返すと、その分スキップするので
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 // 改行までをスキャンし、その分をスキップ
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 return (int)(*(anychar_p - '\n') >> ch_p('\n')).parse(scan).length();
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 private:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 const char *msg_;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 } ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 typedef functor_parser<error_parser> error_p;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 // エラー処理パーサー定義
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 error_p syntax_error_p = error_parser("文法エラー");
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 // ノードに値を設定する
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 struct set_value {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 set_value(int id): id_(id){}
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 void operator()(tree_node< node_val_data<iterator_t, int> >& node,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 iterator_t b, iterator_t e) const
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 node.value.value(id_);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 int id_;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 } ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 // 文法定義
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 struct calc_grammer: public grammar<calc_grammer> {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 enum {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 OP_NOP,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 OP_IDENTIFIER,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 OP_NUMBER,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 OP_NEG,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 OP_MUL,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 OP_DIV,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 OP_ADD,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 OP_SUB,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 OP_ASSIGN,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 OP_PRINT,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 OP_LIST,
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 } ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 template <typename ScannerT>
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 struct definition {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 rule<ScannerT> identifier;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 rule<ScannerT> number;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 rule<ScannerT> prime;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 rule<ScannerT> unary;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 rule<ScannerT> mul_expr;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 rule<ScannerT> add_expr;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 rule<ScannerT> assign;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 rule<ScannerT> print;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 rule<ScannerT> list;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 rule<ScannerT> statement;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 rule<ScannerT> input;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 definition(calc_grammer const& self)
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 identifier = access_node_d[leaf_node_d[lexeme_d[alpha_p >> *alnum_p]]][set_value(OP_IDENTIFIER)];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 number = access_node_d[uint_p][set_value(OP_NUMBER)];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 prime = identifier
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 | number
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 | inner_node_d['(' >> add_expr >> ')']
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 unary = prime
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 | access_node_d[root_node_d[ch_p('-')]][set_value(OP_NEG)] >> prime
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 mul_expr = unary % root_node_d[access_node_d[ch_p('*')][set_value(OP_MUL)] | access_node_d[ch_p('/')][set_value(OP_DIV)]];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 add_expr = mul_expr % root_node_d[access_node_d[ch_p('+')][set_value(OP_ADD)] | access_node_d[ch_p('-')][set_value(OP_SUB)]];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 assign = identifier >> access_node_d[root_node_d[ch_p('=')]][set_value(OP_ASSIGN)] >> add_expr;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 print = access_node_d[root_node_d[str_p("print")]][set_value(OP_PRINT)] >> add_expr;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 list = access_node_d[root_node_d[str_p("list")]][set_value(OP_LIST)];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 statement = root_node_d[assign | print | list] >> discard_node_d[ch_p('\n')];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 // 入力は、「文」、「空行」もしくは「エラー」
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 input = *(statement | discard_node_d[ch_p('\n')] | syntax_error_p);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 rule<ScannerT> const& start() const
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 return input;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 } ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 } ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 // ツリーのイテレータから、変数を取り出す
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 int &value_ref(const tree_iter_t &it)
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 return values[string(it->value.begin(), it->value.end())];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 // リストコマンドの関数オブジェクト
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 struct list_action {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 void operator()(const std::pair<std::string, int> &it)
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 cout << it.first << " = " << it.second << endl;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 } ;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 int eval(const tree_iter_t &it)
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 switch (it->value.value()) {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 case calc_grammer::OP_NEG:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 assert(it->children.size() == 1);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 return -eval(it->children.begin());
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 case calc_grammer::OP_ADD:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 assert(it->children.size() == 2);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 return eval(it->children.begin()) + eval(it->children.begin() + 1);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 case calc_grammer::OP_SUB:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 assert(it->children.size() == 2);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 return eval(it->children.begin()) - eval(it->children.begin() + 1);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 case calc_grammer::OP_MUL:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 assert(it->children.size() == 2);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 return eval(it->children.begin()) * eval(it->children.begin() + 1);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 case calc_grammer::OP_DIV:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 assert(it->children.size() == 2);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 return eval(it->children.begin()) / eval(it->children.begin() + 1);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 case calc_grammer::OP_ASSIGN:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 assert(it->children.size() == 2);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 return value_ref(it->children.begin()) = eval(it->children.begin() + 1);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 case calc_grammer::OP_IDENTIFIER:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 return values[string(it->value.begin(), it->value.end())];
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 case calc_grammer::OP_NUMBER:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 return atoi(string(it->value.begin(), it->value.end()).c_str());
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 case calc_grammer::OP_PRINT:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 cout << eval(it->children.begin()) << endl;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 break;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 case calc_grammer::OP_LIST:
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 for_each(values.begin(), values.end(), list_action());
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 break;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 return 0;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 // main
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 int main(int argc, char *argv[])
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 // ファイルの読み込みに、file_iteratorを使用する
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 file_iterator<> first("input.txt");
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 if (!first) {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 cout << "ファイルがオープンできません。" << endl;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 return 1;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 file_iterator<> last = first.make_end();
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 // 抽象構文木作成
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 calc_grammer gr;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 tree_parse_info<iterator_t, factory_t> info; // 解析情報を保持する変数
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 info = ast_parse(first, last, gr, ch_p(' ') | ch_p('\t') | ch_p('\r'), factory_t());
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 if (info.full) {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 const tree_iter_t &root = info.trees.begin();
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 size_t size = root->children.size();
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 for(size_t i=0; i<size; i++) {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 eval(root->children.begin() + i);
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 else {
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 // エラー処理が入っているので、エラー処理されるとここには来ない
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 // エラー処理パーサーで、エラー処理を行ったら失敗としたほうが
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 // 良い。
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 cout << "構文解析失敗" << endl;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 }
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 return 0;
db40c85cad7a upload sample source
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 }