4 * Created on: Aug 26, 2012
20 void Parser::Parse() {
21 while (tok.HasMore()) {
26 void Parser::ParseStatement() {
27 Tokenizer::Token t(GetToken());
29 case Tokenizer::Token::KEYWORD_EXPORT:
30 ParseExportDirective();
32 case Tokenizer::Token::KEYWORD_INCLUDE:
33 ParseIncludeDirective();
35 case Tokenizer::Token::TYPE_NAME:
38 Declaration *decl(ProbeDefinition());
39 product.AddDeclaration(decl);
43 throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type));
47 Tokenizer::Token Parser::GetToken() {
50 } catch (Tokenizer::LexerError &e) {
51 throw Error(file, e.Line(), e.what());
55 void Parser::ParseExportDirective() {
56 Tokenizer::Token t(GetToken());
57 if (t.type != Tokenizer::Token::IDENTIFIER) {
59 Declaration *decl(ProbeDefinition());
60 product.ExportDeclaration(decl);
62 product.ExportIdentifier(t.str);
66 void Parser::ParseIncludeDirective() {
67 Tokenizer::Token t(GetToken());
68 AssertTokenType(t.type, Tokenizer::Token::STRING);
69 Parser sub(t.str.c_str(), product); // TODO: resolve path name
73 Declaration *Parser::ProbeDefinition() {
74 string typeName(ParseTypeName());
75 string identifier(ParseIdentifier());
77 Tokenizer::Token t(GetToken());
79 if (BeginOfPropertyList(t)) {
80 PropertyList *propertyList(ParsePropertyList());
81 Definition *dfn(new Definition(typeName, identifier));
82 dfn->SetValue(propertyList);
84 } else if (BeginningOfLiteral(t)) {
85 Literal *literal(ParseLiteral());
86 Definition *dfn(new Definition(typeName, identifier));
87 dfn->SetValue(literal);
90 return new Declaration(typeName, identifier);
94 bool Parser::BeginningOfLiteral(const Tokenizer::Token &t) const {
96 case Tokenizer::Token::CHEVRON_OPEN:
97 case Tokenizer::Token::BRACKET_OPEN:
98 case Tokenizer::Token::PARENTHESIS_OPEN:
99 case Tokenizer::Token::NUMBER:
100 case Tokenizer::Token::STRING:
101 case Tokenizer::Token::KEYWORD_FALSE:
102 case Tokenizer::Token::KEYWORD_TRUE:
103 case Tokenizer::Token::TYPE_NAME:
110 bool Parser::BeginOfPropertyList(const Tokenizer::Token &t) const {
111 return t.type == Tokenizer::Token::ANGLE_BRACKET_OPEN;
114 Definition *Parser::ParseDefinition() {
115 string typeName(ParseTypeName());
116 string identifier(ParseIdentifier());
118 Tokenizer::Token t(GetToken());
120 if (BeginOfPropertyList(t)) {
121 PropertyList *propertyList(ParsePropertyList());
122 Definition *dfn(new Definition(typeName, identifier));
123 dfn->SetValue(propertyList);
125 } else if (BeginningOfLiteral(t)) {
126 Literal *literal(ParseLiteral());
127 Definition *dfn(new Definition(typeName, identifier));
128 dfn->SetValue(literal);
131 throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected property-list or literal");
135 string Parser::ParseIdentifier() {
136 Tokenizer::Token t(GetToken());
137 AssertTokenType(t.type, Tokenizer::Token::IDENTIFIER);
141 string Parser::ParseTypeName() {
142 Tokenizer::Token t(GetToken());
143 AssertTokenType(t.type, Tokenizer::Token::TYPE_NAME);
147 PropertyList *Parser::ParsePropertyList() {
148 Tokenizer::Token t(GetToken());
149 AssertTokenType(t.type, Tokenizer::Token::ANGLE_BRACKET_OPEN);
151 auto_ptr<PropertyList> props(new PropertyList);
153 while (t.type != Tokenizer::Token::ANGLE_BRACKET_CLOSE) {
154 Tokenizer::Token name(GetToken());
155 AssertTokenType(name.type, Tokenizer::Token::IDENTIFIER);
158 AssertTokenType(t.type, Tokenizer::Token::COLON);
160 Value *value(ParseValue());
161 props->SetProperty(name.str, value);
164 if (t.type != Tokenizer::Token::ANGLE_BRACKET_CLOSE && t.type != Tokenizer::Token::COMMA) {
165 throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or }");
169 return props.release();
172 Value *Parser::ParseValue() {
173 Tokenizer::Token t(GetToken());
174 if (t.type == Tokenizer::Token::IDENTIFIER) {
175 return new Value(t.str);
176 } else if (BeginningOfLiteral(t)) {
178 Literal *literal(ParseLiteral());
179 return new Value(literal);
181 throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected literal or identifier");
185 Literal *Parser::ParseLiteral() {
186 Tokenizer::Token t(GetToken());
187 if (t.type == Tokenizer::Token::TYPE_NAME) {
188 PropertyList *props(ParsePropertyList());
189 return new Literal(t.str, props);
190 } else if (BeginningOfLiteral(t)) {
192 case Tokenizer::Token::CHEVRON_OPEN:
194 return ParseVector();
195 case Tokenizer::Token::BRACKET_OPEN:
198 case Tokenizer::Token::PARENTHESIS_OPEN:
201 case Tokenizer::Token::NUMBER:
202 return new Literal(t.number);
203 case Tokenizer::Token::STRING:
204 return new Literal(t.str);
205 case Tokenizer::Token::KEYWORD_FALSE:
206 return new Literal(false);
207 case Tokenizer::Token::KEYWORD_TRUE:
208 return new Literal(true);
210 throw std::logic_error("literal switch reached impossible default branch oO");
213 throw new Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected type-name or primitive");
217 Literal *Parser::ParseArray() {
218 Tokenizer::Token t(GetToken());
219 AssertTokenType(t.type, Tokenizer::Token::BRACKET_OPEN);
221 vector<Value *> values;
223 while (t.type != Tokenizer::Token::ANGLE_BRACKET_CLOSE) {
224 Value *value(ParseValue());
225 values.push_back(value);
228 if (t.type != Tokenizer::Token::BRACKET_CLOSE && t.type != Tokenizer::Token::COMMA) {
229 throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or ]");
233 return new Literal(values);
236 Literal *Parser::ParseColor() {
237 string msg("error parsing color");
238 Tokenizer::Token t(GetToken());
239 AssertTokenType(t.type, Tokenizer::Token::PARENTHESIS_OPEN, msg);
241 Tokenizer::Token red(GetToken());
242 AssertTokenType(red.type, Tokenizer::Token::NUMBER, "error parsing red component of color");
245 AssertTokenType(t.type, Tokenizer::Token::COMMA, msg);
247 Tokenizer::Token green(GetToken());
248 AssertTokenType(green.type, Tokenizer::Token::NUMBER, "error parsing green component of color");
251 AssertTokenType(t.type, Tokenizer::Token::COMMA, msg);
253 Tokenizer::Token blue(GetToken());
254 AssertTokenType(blue.type, Tokenizer::Token::NUMBER, "error parsing blue component of color");
257 if (t.type == Tokenizer::Token::BRACKET_CLOSE) {
258 return new Literal(red.number, green.number, blue.number);
259 } else if (t.type != Tokenizer::Token::COMMA) {
260 Tokenizer::Token alpha(GetToken());
261 AssertTokenType(alpha.type, Tokenizer::Token::NUMBER, "error parsing alpha component of color");
264 AssertTokenType(t.type, Tokenizer::Token::PARENTHESIS_CLOSE, msg);
266 return new Literal(red.number, green.number, blue.number, alpha.number);
268 throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or ]");
272 Literal *Parser::ParseVector() {
273 std::string msg("error parsing vector");
274 Tokenizer::Token t(GetToken());
275 AssertTokenType(t.type, Tokenizer::Token::CHEVRON_OPEN, msg);
277 Tokenizer::Token x(GetToken());
278 AssertTokenType(x.type, Tokenizer::Token::NUMBER, "error parsing x component of vector");
281 AssertTokenType(t.type, Tokenizer::Token::COMMA, msg);
283 Tokenizer::Token y(GetToken());
284 AssertTokenType(y.type, Tokenizer::Token::NUMBER, "error parsing y component of vector");
287 AssertTokenType(t.type, Tokenizer::Token::CHEVRON_CLOSE, msg);
289 return new Literal(x.number, y.number);
292 void Parser::AssertTokenType(Tokenizer::Token::Type actual, Tokenizer::Token::Type expected) {
293 if (expected != actual) {
294 throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(actual) + ", expected " + TokenTypeToString(expected));
298 void Parser::AssertTokenType(Tokenizer::Token::Type actual, Tokenizer::Token::Type expected, const string &msg) {
299 if (expected != actual) {
300 throw Error(file, tok.Line(), msg + ": unexpected token " + TokenTypeToString(actual) + ", expected " + TokenTypeToString(expected));