File: State.h

package info (click to toggle)
storm-lang 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,028 kB
  • sloc: ansic: 261,471; cpp: 140,432; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (195 lines) | stat: -rw-r--r-- 5,451 bytes parent folder | download | duplicates (2)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#pragma once
#include "Compiler/Syntax/Production.h"
#include "Core/PODArray.h"

namespace storm {
	namespace syntax {
		namespace earley {
			STORM_PKG(lang.bnf.earley);

			class Parser;

			/**
			 * Pointer to a state in some StateSet. Represented by two integers: the step and the index
			 * into that step. Null is represented by step and index being (Nat)-1.
			 */
			class StatePtr {
				STORM_VALUE;
			public:
				// Create invalid state pointer.
				STORM_CTOR StatePtr();

				// Create to a specific state.
				STORM_CTOR StatePtr(Nat step, Nat index);

				// The step.
				Nat step;

				// Index inside that step.
				Nat index;

				// Compare.
				inline Bool STORM_FN operator ==(const StatePtr &o) const {
					return step == o.step && index == o.index;
				}

				inline Bool STORM_FN operator !=(const StatePtr &o) const {
					return !(*this == o);
				}

				// Output.
				void STORM_FN toS(StrBuf *to) const;
			};

			wostream &operator <<(wostream &to, StatePtr p);

			/**
			 * State used during parsing (in Parser.h/cpp). Contains a location into a production, a
			 * step where the option was instantiated, a pointer to the previous step and optionally the
			 * step that was completed.
			 */
			class State {
				STORM_VALUE;
			public:
				// Create.
				STORM_CTOR State();
				STORM_CTOR State(ProductionIter pos, Nat from);
				STORM_CTOR State(ProductionIter pos, Nat from, StatePtr prev);
				STORM_CTOR State(ProductionIter pos, Nat from, StatePtr prev, StatePtr completed);

				// Position in the production.
				ProductionIter pos;

				// The step where this production was instantiated.
				Nat from;

				// Previous instance of this state.
				StatePtr prev;

				// State that completed this state. If set, this means that pos->token is a rule token.
				StatePtr completed;

				// Is this a valid state (ie. does it have a valid position?)
				inline Bool valid() const {
					return pos.valid();
				}

				// Get the priority for the rule associated with this state.
				inline Int priority() const {
					return pos.production()->priority;
				}

				// Get the production this state represents.
				inline Production *production() const {
					return pos.production();
				}

				// See if this state is a Rule token.
				inline RuleToken *getRule() const {
					Token *t = pos.token();
					return t ? t->asRule() : null;
				}

				// See if this state is a Regex token.
				inline RegexToken *getRegex() const {
					Token *t = pos.token();
					return t ? t->asRegex() : null;
				}

				// See if this state finishes a production.
				inline Bool finishes(Production *p) const {
					return production() == p
						&& pos.end();
				}

				// Equality, as required by the parser. TODO: adhere to the future standard equal interface.
				inline Bool STORM_FN operator ==(const State &o) const {
					return pos == o.pos
						&& from == o.from;
				}

				inline Bool STORM_FN operator !=(const State &o) const {
					return !(*this == o);
				}

				// Output.
				void STORM_FN toS(StrBuf *to) const;
			};

			// To string.
			wostream &operator <<(wostream &to, State s);


			/**
			 * Ordered set of states. Supports proper ordering by priority.
			 */
			class StateSet : public Object {
				STORM_CLASS;
			public:
				// Create.
				StateSet();

				// Insert a state here if it does not exist. May alter the 'completed' member of an
				// existing state to obey priority rules.
				void STORM_FN push(Parser *parser, const State &state);

				// Insert a new state (we will allocate it for you if neccessary)
				void STORM_FN push(Parser *parser, ProductionIter pos, Nat from);
				void STORM_FN push(Parser *parser, ProductionIter pos, Nat from, StatePtr prev);
				void STORM_FN push(Parser *parser, ProductionIter pos, Nat from, StatePtr prev, StatePtr completed);

				// Current size of this set.
				inline Nat STORM_FN count() const {
					if (chunks == null)
						return 0;
					if (chunks->filled == 0)
						return 0;
					nat last = Nat(chunks->filled - 1);
					return last*chunkSize + Nat(chunks->v[last]->filled);
				}

				// Get an element in this set.
				inline const State &STORM_FN operator [](Nat i) const {
					GcArray<State> *chunk = chunks->v[i >> chunkBits];
					return chunk->v[i & chunkMask];
				}

			private:
				// Chunk size. Must be a power of two.
				enum {
					chunkBits = 5,
					chunkSize = (1 << chunkBits),
					chunkMask = chunkSize - 1
				};

				// State data. Represented as a two-level array to avoid copying.
				GcArray<GcArray<State> *> *chunks;

				// The GcType for arrays of State objects.
				const GcType *stateArrayType;

				// Size of the array to use when computing production ordering. Should be large enough
				// to cover the majority of productions, otherwise we loose performance.
				typedef PODArray<StatePtr, 20> StateArray;

				// Ordering.
				enum Order {
					before,
					after,
					none,
				};

				// Compute the execution order of two states when parsed by a top-down parser.
				Order execOrder(Parser *parser, const StatePtr &a, const StatePtr &b) const;
				Order execOrder(Parser *parser, const State &a, const State &b) const;

				// Find the 'completed' field for previous states. May contain entries representing null.
				void prevCompleted(Parser *parser, const State &from, StateArray &to) const;

				// Ensure we have at least 'n' chunks.
				void ensure(Nat n);
			};

		}
	}
}