This repository was archived by the owner on Apr 13, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython_grammar.cxx
More file actions
105 lines (91 loc) · 3.63 KB
/
python_grammar.cxx
File metadata and controls
105 lines (91 loc) · 3.63 KB
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
#include "python_grammar.h"
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_char_.hpp>
#include <boost/spirit/include/qi_eps.hpp>
#include <boost/spirit/include/qi_kleene.hpp>
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_operator.hpp>
#include <boost/spirit/include/qi_real.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include "symbols.h"
namespace sap
{
PythonGrammar::PythonGrammar()
: base_type( start )
{
using qi::ascii::char_;
using qi::ascii::alnum;
using qi::ascii::alpha;
using qi::labels::_val;
using qi::labels::_1;
using qi::lit;
using qi::eps;
using qi::double_;
static Symbols symbols;
static ReservedWords reserved_words;
// match 4 spaces
indent = lit(" ");
// calculate indent level
indent_level = eps [ _val = 0 ]
// for every indent, increase _val
>> *indent [ _val += 1 ];
// dummy, sets lex.type_ field
indent_type = eps [ _val = lex::type::INDENT ];
indent_rule %= indent_type
>> indent_level;
// dummy, sets lex.type_ field
symbol_type = eps [ _val = lex::type::SYMBOL ];
// match symbols against symbol-table
symbol %= symbols;
symbol_rule %= symbol_type
>> symbol;
// dummy, sets lex.type_ field
reserved_type = eps [ _val = lex::type::RESERVED ];
// match against symbol table
reserved %= reserved_words;
reserved_rule %= reserved_type
>> reserved;
// dummy, sets lex.type_ field
identifier_type = eps [ _val = lex::type::IDENTIFIER ];
identifier %= (alpha | char_('_')) // letter or _
// followed by letter, number or _ undetermined number of times
>> *(alnum | char_('_'));
identifier_rule = identifier_type
>> identifier;
s_type = eps [ _val = lex::type::S_CONST ];
d_type = eps [ _val = lex::type::D_CONST ];
b_type = eps [ _val = lex::type::B_CONST ];
double_constant %= double_;
// bool constant is either True or False
bool_constant = lit("True") [ _val = true ]
| lit("False") [ _val = false ];
// string constant is any number of characters between " "
string_constant %= lit("\"")
>> *(char_ - char_('"'))
>> lit("\"");
// constant is either double, or bool, or string constant
constant_rule %=
( d_type >> double_constant )
| ( b_type >> bool_constant )
| ( s_type >> string_constant );
// matches all lexemes, that a visible (not indent & newline )
// it's either reserved word, or constant, or identifier, or symbol
visible_lexeme %= reserved_rule
| constant_rule
| identifier_rule
| symbol_rule
;
// Matches only indent, but doesn't set anything (it's type is void)
empty_line = indent_rule;
// Matches typical line (indent, followed by visible_lexeme s )
non_empty_line %= indent_rule
>> +( // one or more
*lit(" ") // ignore spaces
>> visible_lexeme // some visible_lexeme
>> *lit(" ") // ignore spaces
);
start = non_empty_line [ _val = _1 ]
| empty_line;
}
} // namespace sap