-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathbfparser.h
108 lines (89 loc) · 3.94 KB
/
bfparser.h
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
107
108
// bfparser.h
// brainfuck
//
// Created by Xu Chen on 12-9-8.
// Copyright (c) 2012 Xu Chen. All rights reserved.
//
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include "bfast.h"
#ifndef brainfuck_bfparser_h
#define brainfuck_bfparser_h
namespace brainfuck {
namespace parser {
template<typename Iterator>
struct skipper : boost::spirit::qi::grammar<Iterator> {
skipper() : skipper::base_type(start) {
using boost::spirit::ascii::char_;
using boost::spirit::no_skip;
using boost::spirit::lexeme;
// All chars other than these 8 are ignored
start = char_ - char_("-<>+,.[]")
;
}
boost::spirit::qi::rule<Iterator> start;
};
template<typename Iterator>
struct parser : boost::spirit::qi::grammar<Iterator, ast::Program(), skipper<Iterator> > {
parser() : parser::base_type(program) {
using boost::spirit::ascii::char_;
program = +command >> boost::spirit::eoi
;
loop = '[' >> *command >> ']'
;
command = loop
| primitive
;
primitive = moveleft
| moveright
| add
| minus
| input
| output
;
moveleft = +char_('<')
;
moveright = +char_('>')
;
add = +char_('+')
;
minus = +char_('-')
;
input = char_(',')
;
output = char_('.')
;
BOOST_SPIRIT_DEBUG_NODE(program);
BOOST_SPIRIT_DEBUG_NODE(command);
BOOST_SPIRIT_DEBUG_NODE(loop);
BOOST_SPIRIT_DEBUG_NODE(primitive);
BOOST_SPIRIT_DEBUG_NODE(moveleft);
BOOST_SPIRIT_DEBUG_NODE(moveright);
BOOST_SPIRIT_DEBUG_NODE(add);
BOOST_SPIRIT_DEBUG_NODE(minus);
BOOST_SPIRIT_DEBUG_NODE(input);
BOOST_SPIRIT_DEBUG_NODE(output);
}
bool parse(Iterator first, Iterator last, ast::Program& prog) {
return boost::spirit::qi::phrase_parse(first, last, *this, skipper<Iterator>(), prog);
}
boost::spirit::qi::rule<Iterator, ast::Program(), skipper<Iterator> > program;
boost::spirit::qi::rule<Iterator, ast::Command(), skipper<Iterator> > command;
boost::spirit::qi::rule<Iterator, ast::Loop(), skipper<Iterator> > loop;
boost::spirit::qi::rule<Iterator, ast::Primitive(), skipper<Iterator> > primitive;
boost::spirit::qi::rule<Iterator, ast::MoveLeft(), skipper<Iterator> > moveleft;
boost::spirit::qi::rule<Iterator, ast::MoveRight(), skipper<Iterator> > moveright;
boost::spirit::qi::rule<Iterator, ast::Add(), skipper<Iterator> > add;
boost::spirit::qi::rule<Iterator, ast::Minus(), skipper<Iterator> > minus;
boost::spirit::qi::rule<Iterator, ast::Input(), skipper<Iterator> > input;
boost::spirit::qi::rule<Iterator, ast::Output(), skipper<Iterator> > output;
}; // End of parser
template<typename Iterator>
bool parse(Iterator first, Iterator last, ast::Program &prog) {
parser<Iterator> parser;
return parser.parse(first, last, prog);
}
} // End of namespace parser
} // End of namespace brainfuck
#endif