4 * Created on: Aug 26, 2012
20 void Parser::Parse() {
21 while (tok.HasMore()) {
26 void Parser::ParseStatement() {
27 Tokenizer::Token t(tok.GetNext());
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 ParseError(string("unexpected token ") + TokenTypeToString(t.type));
47 void Parser::ParseExportDirective() {
48 Tokenizer::Token t(tok.GetNext());
49 if (t.type != Tokenizer::Token::IDENTIFIER) {
51 Declaration *decl(ProbeDefinition());
52 product.ExportDeclaration(decl);
54 product.ExportIdentifier(t.str);
58 void Parser::ParseIncludeDirective() {
59 Tokenizer::Token t(tok.GetNext());
60 AssertTokenType(t.type, Tokenizer::Token::STRING);
61 ifstream file(t.str.c_str()); // TODO: resolve path name
62 Parser sub(file, product);
66 Declaration *Parser::ProbeDefinition() {
67 string typeName(ParseTypeName());
68 string identifier(ParseIdentifier());
70 Tokenizer::Token t(tok.GetNext());
72 if (BeginOfPropertyList(t)) {
73 PropertyList *propertyList(ParsePropertyList());
74 Definition *dfn(new Definition(typeName, identifier));
75 dfn->SetValue(propertyList);
77 } else if (BeginningOfLiteral(t)) {
78 Literal *literal(ParseLiteral());
79 Definition *dfn(new Definition(typeName, identifier));
80 dfn->SetValue(literal);
83 return new Declaration(typeName, identifier);
87 bool Parser::BeginningOfLiteral(const Tokenizer::Token &t) const {
89 case Tokenizer::Token::CHEVRON_OPEN:
90 case Tokenizer::Token::BRACKET_OPEN:
91 case Tokenizer::Token::PARENTHESIS_OPEN:
92 case Tokenizer::Token::NUMBER:
93 case Tokenizer::Token::STRING:
94 case Tokenizer::Token::KEYWORD_FALSE:
95 case Tokenizer::Token::KEYWORD_TRUE:
96 case Tokenizer::Token::TYPE_NAME:
103 bool Parser::BeginOfPropertyList(const Tokenizer::Token &t) const {
104 return t.type == Tokenizer::Token::ANGLE_BRACKET_OPEN;
107 Definition *Parser::ParseDefinition() {
108 string typeName(ParseTypeName());
109 string identifier(ParseIdentifier());
111 Tokenizer::Token t(tok.GetNext());
113 if (BeginOfPropertyList(t)) {
114 PropertyList *propertyList(ParsePropertyList());
115 Definition *dfn(new Definition(typeName, identifier));
116 dfn->SetValue(propertyList);
118 } else if (BeginningOfLiteral(t)) {
119 Literal *literal(ParseLiteral());
120 Definition *dfn(new Definition(typeName, identifier));
121 dfn->SetValue(literal);
124 throw ParseError(string("unexpected token ") + TokenTypeToString(t.type) + ", expected property-list or literal");
128 string Parser::ParseIdentifier() {
129 Tokenizer::Token t(tok.GetNext());
130 AssertTokenType(t.type, Tokenizer::Token::IDENTIFIER);
134 string Parser::ParseTypeName() {
135 Tokenizer::Token t(tok.GetNext());
136 AssertTokenType(t.type, Tokenizer::Token::TYPE_NAME);
140 PropertyList *Parser::ParsePropertyList() {
141 Tokenizer::Token t(tok.GetNext());
142 AssertTokenType(t.type, Tokenizer::Token::ANGLE_BRACKET_OPEN);
144 auto_ptr<PropertyList> props(new PropertyList);
146 while (t.type != Tokenizer::Token::ANGLE_BRACKET_CLOSE) {
147 Tokenizer::Token name(tok.GetNext());
148 AssertTokenType(name.type, Tokenizer::Token::IDENTIFIER);
151 AssertTokenType(t.type, Tokenizer::Token::COLON);
153 Value *value(ParseValue());
154 props->SetProperty(name.str, value);
157 if (t.type != Tokenizer::Token::ANGLE_BRACKET_CLOSE && t.type != Tokenizer::Token::COMMA) {
158 throw ParseError(string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or }");
162 return props.release();
165 Value *Parser::ParseValue() {
166 Tokenizer::Token t(tok.GetNext());
167 if (t.type == Tokenizer::Token::IDENTIFIER) {
168 return new Value(t.str);
169 } else if (BeginningOfLiteral(t)) {
171 Literal *literal(ParseLiteral());
172 return new Value(literal);
174 throw new ParseError(string("unexpected token ") + TokenTypeToString(t.type) + ", expected literal or identifier");
178 Literal *Parser::ParseLiteral() {
179 Tokenizer::Token t(tok.GetNext());
180 if (t.type == Tokenizer::Token::TYPE_NAME) {
181 PropertyList *props(ParsePropertyList());
182 return new Literal(t.str, props);
183 } else if (BeginningOfLiteral(t)) {
185 case Tokenizer::Token::CHEVRON_OPEN:
187 return ParseVector();
188 case Tokenizer::Token::BRACKET_OPEN:
191 case Tokenizer::Token::PARENTHESIS_OPEN:
194 case Tokenizer::Token::NUMBER:
195 return new Literal(t.number);
196 case Tokenizer::Token::STRING:
197 return new Literal(t.str);
198 case Tokenizer::Token::KEYWORD_FALSE:
199 return new Literal(false);
200 case Tokenizer::Token::KEYWORD_TRUE:
201 return new Literal(true);
203 throw std::logic_error("literal switch reached impossible default branch oO");
206 throw new ParseError(string("unexpected token ") + TokenTypeToString(t.type) + ", expected type-name or primitive");
210 Literal *Parser::ParseArray() {
211 Tokenizer::Token t(tok.GetNext());
212 AssertTokenType(t.type, Tokenizer::Token::BRACKET_OPEN);
214 vector<Value *> values;
216 while (t.type != Tokenizer::Token::ANGLE_BRACKET_CLOSE) {
217 Value *value(ParseValue());
218 values.push_back(value);
221 if (t.type != Tokenizer::Token::BRACKET_CLOSE && t.type != Tokenizer::Token::COMMA) {
222 throw ParseError(string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or ]");
226 return new Literal(values);
229 Literal *Parser::ParseColor() {
230 string msg("error parsing color");
231 Tokenizer::Token t(tok.GetNext());
232 AssertTokenType(t.type, Tokenizer::Token::PARENTHESIS_OPEN, msg);
234 Tokenizer::Token red(tok.GetNext());
235 AssertTokenType(red.type, Tokenizer::Token::NUMBER, "error parsing red component of color");
238 AssertTokenType(t.type, Tokenizer::Token::COMMA, msg);
240 Tokenizer::Token green(tok.GetNext());
241 AssertTokenType(green.type, Tokenizer::Token::NUMBER, "error parsing green component of color");
244 AssertTokenType(t.type, Tokenizer::Token::COMMA, msg);
246 Tokenizer::Token blue(tok.GetNext());
247 AssertTokenType(blue.type, Tokenizer::Token::NUMBER, "error parsing blue component of color");
250 if (t.type == Tokenizer::Token::BRACKET_CLOSE) {
251 return new Literal(red.number, green.number, blue.number);
252 } else if (t.type != Tokenizer::Token::COMMA) {
253 Tokenizer::Token alpha(tok.GetNext());
254 AssertTokenType(alpha.type, Tokenizer::Token::NUMBER, "error parsing alpha component of color");
257 AssertTokenType(t.type, Tokenizer::Token::PARENTHESIS_CLOSE, msg);
259 return new Literal(red.number, green.number, blue.number, alpha.number);
261 throw ParseError(string("unexpected token ") + TokenTypeToString(t.type) + ", expected , or ]");
265 Literal *Parser::ParseVector() {
266 std::string msg("error parsing vector");
267 Tokenizer::Token t(tok.GetNext());
268 AssertTokenType(t.type, Tokenizer::Token::CHEVRON_OPEN, msg);
270 Tokenizer::Token x(tok.GetNext());
271 AssertTokenType(x.type, Tokenizer::Token::NUMBER, "error parsing x component of vector");
274 AssertTokenType(t.type, Tokenizer::Token::COMMA, msg);
276 Tokenizer::Token y(tok.GetNext());
277 AssertTokenType(y.type, Tokenizer::Token::NUMBER, "error parsing y component of vector");
280 AssertTokenType(t.type, Tokenizer::Token::CHEVRON_CLOSE, msg);
282 return new Literal(x.number, y.number);
285 void Parser::AssertTokenType(Tokenizer::Token::Type actual, Tokenizer::Token::Type expected) {
286 if (expected != actual) {
287 throw ParseError(string("unexpected token ") + TokenTypeToString(actual) + ", expected " + TokenTypeToString(expected));
291 void Parser::AssertTokenType(Tokenizer::Token::Type actual, Tokenizer::Token::Type expected, const string &msg) {
292 if (expected != actual) {
293 throw ParseError(msg + ": unexpected token " + TokenTypeToString(actual) + ", expected " + TokenTypeToString(expected));