-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.hpp
106 lines (84 loc) · 4.75 KB
/
parser.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#ifndef __GIKO_PARSER_HPP
#define __GIKO_PARSER_HPP
#include <string>
#include <vector>
#include <boost/fusion/tuple.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include "ast.hpp"
namespace giko
{
namespace parser
{
using namespace boost::spirit;
using namespace giko::ast;
template<typename Iterator, typename Skipper>
struct giko_grammar : qi::grammar<Iterator, ModuleAST *(), Skipper>
{
qi::rule<Iterator, std::string(), Skipper> id;
qi::rule<Iterator, std::vector<std::string>(), Skipper> vars;
qi::rule<Iterator, FunctionAST *(), Skipper> func;
qi::rule<Iterator, ModuleAST *(), Skipper> module;
qi::rule<Iterator, BaseAST *(), Skipper> statement;
qi::rule<Iterator, BuiltinAST *(), Skipper> builtin;
qi::rule<Iterator, AssignAST *(), Skipper> assign;
qi::rule<Iterator, IfStatementAST *(), Skipper> if_statement;
qi::rule<Iterator, WhileStatementAST *(), Skipper> while_statement;
qi::rule<Iterator, StatementsAST *(), Skipper> statements;
qi::rule<Iterator, BaseAST *(), Skipper> l0, l1, l2, l3, l4, expr;
giko_grammar() : giko_grammar::base_type(module)
{
using namespace boost::spirit::qi;
using namespace boost::phoenix;
using namespace boost;
// 識別子
id = lexeme[alpha[_val = _1] >> *(alnum[_val += _1])];
// 変数宣言
vars = "ヘンスウ" >> id[push_back(_val, _1)] >> *(',' >> id[push_back(_val, _1)]);
// 関数
func = "メジルシ" >> id[_val = new_<FunctionAST>(_1)] >> *statements[push_back(phoenix::at_c<1>(*_val), _1)];
// モジュール
module = vars[_val = new_<ModuleAST>(), phoenix::at_c<0>(*_val) = _1] >> *func[push_back(phoenix::at_c<1>(*_val), _1)];
// 文
statement = builtin | assign | if_statement | while_statement;
// 代入
assign = id[_val = new_<AssignAST>(_1)] >> '=' >> expr[phoenix::at_c<1>(*_val) = _1];
// 組み込み命令
builtin = ("ホザケ" >> id[_val = new_<BuiltinAST>("print"), push_back(phoenix::at_c<1>(*_val), new_<IdentifierAST>(_1))])
| ("イレテミロ" >> id[_val = new_<BuiltinAST>("scan"), push_back(phoenix::at_c<1>(*_val), new_<IdentifierAST>(_1))])
| ("シネ" >> eps[_val = new_<BuiltinAST>("exit")])
| ("ランスウ" >> id[_val = new_<BuiltinAST>("rand"), push_back(phoenix::at_c<1>(*_val), new_<IdentifierAST>(_1))])
| ("イッテコイ" >> id[_val = new_<BuiltinAST>("call"), push_back(phoenix::at_c<1>(*_val), new_<IdentifierAST>(_1))])
| ("カエレ" >> eps[_val = new_<BuiltinAST>("return")])
| ("ヌケダセ" >> eps[_val = new_<BuiltinAST>("break")])
| ("ツヅケロ" >> eps[_val = new_<BuiltinAST>("continue")]);
// if文
if_statement = "モシモダヨ" >> expr[_val = new_<IfStatementAST>(), phoenix::at_c<0>(*_val) = _1]
>> "ダッタラ" >> statements[phoenix::at_c<1>(*_val) = _1]
>> -("ジャナイナラ" >> statements[phoenix::at_c<2>(*_val) = _1]);
// while文
while_statement = "ループ" >> expr[_val = new_<WhileStatementAST>(), phoenix::at_c<0>(*_val) = _1] >> "カイシ"
>> *statements[push_back(phoenix::at_c<1>(*_val), _1)] >> "ループオワリ";
// 文の集合
statements = eps[_val = new_<StatementsAST>()] >> statement[push_back(phoenix::at_c<0>(*_val), _1)]
>> *(':' >> statement[push_back(phoenix::at_c<0>(*_val), _1)]);
// 式
l0 = int_[_val = new_<NumberAST>(_1)] | id[_val = new_<IdentifierAST>(_1)] | '(' >> expr[_val = _1] >> ')';
l1 = l0[_val = _1] >> *( ('*' >> l0[_val = new_<BinaryExprAST>("*", _val, _1)])
| ('/' >> l0[_val = new_<BinaryExprAST>("/", _val, _1)])
| ('%' >> l0[_val = new_<BinaryExprAST>("%", _val, _1)]));
l2 = l1[_val = _1] >> *( ('+' >> l1[_val = new_<BinaryExprAST>("+", _val, _1)])
| ('-' >> l1[_val = new_<BinaryExprAST>("-", _val, _1)]));
l3 = l2[_val = _1] >> *( ('=' >> l2[_val = new_<BinaryExprAST>("=", _val, _1)])
| ('<' >> l2[_val = new_<BinaryExprAST>("<", _val, _1)])
| ('>' >> l2[_val = new_<BinaryExprAST>(">", _val, _1)])
| ("<=" >> l2[_val = new_<BinaryExprAST>("<=", _val, _1)])
| (">=" >> l2[_val = new_<BinaryExprAST>(">=", _val, _1)]));
l4 = l3[_val = _1] | ("チガウヤツ" >> l3[_val = new_<MonoExprAST>("!", _1)]);
expr = l4[_val = _1] >> *( ("カツ" >> l4[_val = new_<BinaryExprAST>("&&", _val, _1)])
| ("マタハ" >> l4[_val = new_<BinaryExprAST>("||", _val, _1)]));
}
};
}
}
#endif