|
11 | 11 | #include <variant> |
12 | 12 | #include <vector> |
13 | 13 |
|
| 14 | +// OP represents the AST node type for a given nonterminal |
14 | 15 | enum class OP |
15 | 16 | { |
16 | | - SOURCE, |
17 | | - SOURCE_PART, |
18 | | - IMPORT, |
19 | | - UDT, |
20 | | - UDA, |
21 | | - START, |
22 | | - SCRIPT, |
23 | | - VARIABLE, |
24 | | - FUNCTION, |
25 | | - FUNCTION_INFO, |
26 | | - FUNCTION_IN_OUT, |
27 | | - TREE, |
| 17 | + ADDITION, |
| 18 | + ADDTO, |
| 19 | + AND, |
| 20 | + ASSIGNMENT, |
| 21 | + ATTRIBUTE_ACCESS, |
| 22 | + ATTRIBUTE, |
| 23 | + BLOCK, |
28 | 24 | BRANCH, |
| 25 | + DECLARATION, |
| 26 | + DIVFROM, |
| 27 | + DIVISION, |
29 | 28 | E0, |
| 29 | + END, |
| 30 | + EQUIVALENCE, |
30 | 31 | EXPONENT, |
31 | | - MULTIPLICATION, |
32 | | - DIVISION, |
33 | | - MODULO, |
34 | | - ADDITION, |
35 | | - SUBTRACTION, |
36 | | - LESS_THAN, |
37 | | - LESS_THAN_OR_EQUALS, |
38 | | - GREATER_THAN, |
| 32 | + FUNCTION_CALL, |
| 33 | + FUNCTION_IN_OUT, |
| 34 | + FUNCTION_INFO, |
| 35 | + FUNCTION_INPUT, |
| 36 | + FUNCTION, |
39 | 37 | GREATER_THAN_OR_EQUALS, |
40 | | - EQUIVALENCE, |
| 38 | + GREATER_THAN, |
| 39 | + IMPORT, |
| 40 | + INPUT, |
| 41 | + LESS_THAN_OR_EQUALS, |
| 42 | + LESS_THAN, |
| 43 | + MEMBER, |
| 44 | + METHOD_ACCESS, |
| 45 | + METHOD, |
| 46 | + MODULO, |
| 47 | + MULTIPLICATION, |
| 48 | + MULTTO, |
| 49 | + NEGATION, |
41 | 50 | NONEQUIVALENCE, |
42 | | - AND, |
| 51 | + NULL_VAL, |
43 | 52 | OR, |
44 | | - ASSIGNMENT, |
45 | | - NEGATION, |
46 | | - END, |
47 | 53 | PRIMARY, |
48 | | - DECLARATION, |
49 | 54 | RETURN, |
50 | | - ATTRIBUTE, |
51 | | - METHOD, |
52 | | - FUNCTION_INPUT, |
| 55 | + SCRIPT, |
| 56 | + SOURCE_PART, |
| 57 | + SOURCE, |
| 58 | + START, |
53 | 59 | STATEMENT, |
54 | | - BLOCK, |
55 | | - NULL_VAL, |
56 | | - MEMBER, |
57 | | - ATTRIBUTE_ACCESS, |
58 | | - METHOD_ACCESS, |
59 | | - INPUT, |
60 | | - FUNCTION_CALL, |
| 60 | + SUBFROM, |
| 61 | + SUBTRACTION, |
| 62 | + TREE, |
| 63 | + UDA, |
| 64 | + UDT, |
61 | 65 | UDTDEC, |
62 | 66 | UDTDECITEM, |
63 | 67 | UNARYADD, |
64 | 68 | UNARYMINUS, |
65 | | - ADDTO, |
66 | | - SUBFROM, |
67 | | - DIVFROM, |
68 | | - MULTTO, |
| 69 | + VARIABLE, |
69 | 70 | }; |
70 | 71 | std::string disp(OP o); |
71 | 72 |
|
| 73 | +// LIT represents the AST node type for a given terminal |
72 | 74 | enum class LIT |
73 | 75 | { |
74 | | - IDENTIFIER, |
75 | | - STRING, |
76 | 76 | BOOLEAN, |
77 | | - INTEGER, |
78 | 77 | FLOAT, |
| 78 | + IDENTIFIER, |
| 79 | + INTEGER, |
79 | 80 | LIST, |
80 | 81 | LISTTYPE, |
| 82 | + STRING, |
81 | 83 | }; |
82 | 84 | std::string disp(LIT l); |
83 | 85 |
|
| 86 | +// node = nonterminal and leaf = terminal |
84 | 87 | struct LeafLexeme; |
85 | 88 | struct NodeLexeme; |
86 | | -typedef std::variant<std::shared_ptr<NodeLexeme>, std::shared_ptr<LeafLexeme>> |
87 | | - Lexeme; |
| 89 | + |
| 90 | +// type alias for more legible code |
| 91 | +using LeafPtr = std::unique_ptr<LeafLexeme>; |
| 92 | +using NodePtr = std::unique_ptr<NodeLexeme>; |
| 93 | + |
| 94 | +// Lexeme is short for the variant that may either be a node or a leaf, |
| 95 | +// convenient for nonterminals that have one or two children |
| 96 | +// using Lexeme = |
| 97 | +// std::variant<std::shared_ptr<NodeLexeme>, std::shared_ptr<LeafLexeme>>; |
| 98 | +using Lexeme = std::variant<LeafPtr, NodePtr>; |
88 | 99 |
|
89 | 100 | struct LeafLexeme |
90 | 101 | { |
91 | 102 | LIT lit; |
92 | 103 | std::string value; |
93 | 104 | LeafLexeme(LIT l, std::string v) : lit(l), value(v){}; |
94 | 105 | }; |
95 | | -std::shared_ptr<LeafLexeme> makeLeaf(LIT l, std::string v); |
| 106 | +LeafPtr makeLeaf(LIT l, std::string v); |
96 | 107 |
|
97 | 108 | struct NodeLexeme |
98 | 109 | { |
99 | 110 | OP op; |
100 | 111 | Lexeme left; |
101 | 112 | Lexeme right; |
102 | | - NodeLexeme(OP o, Lexeme l, Lexeme r) : op(o), left(l), right(r){}; |
| 113 | + NodeLexeme(OP o, Lexeme l, Lexeme r) |
| 114 | + : op(o), left(std::move(l)), right(std::move(r)){}; |
103 | 115 | }; |
104 | | -std::shared_ptr<NodeLexeme> makeNode(OP o, Lexeme, Lexeme); |
105 | | -std::shared_ptr<NodeLexeme> makeNode(OP o, Lexeme); |
106 | | -std::shared_ptr<NodeLexeme> makeNullNode(); |
| 116 | + |
| 117 | +// overloaded since nonterminal may have only a single child, in that case we |
| 118 | +// utilize the null node constructor |
| 119 | +NodePtr makeNode(OP o, Lexeme, Lexeme); |
| 120 | +NodePtr makeNode(OP o, Lexeme); |
| 121 | +NodePtr makeNullNode(); |
0 commit comments