Example #1
0
		bool	Parser::parseIdentifier (Lexer& lexer, string* output)
		{
			if (lexer.getType () != Lexer::IDENTIFIER)
				return this->fail (lexer, "expected column identifier");

			*output = lexer.getCurrent ();

			lexer.next ();

			return true;
		}
Example #2
0
		bool	Parser::parseValue (Lexer& lexer, Lookup& lookup, Int32u* slot, const Extractor** output)
		{
			const Extractor*	argument;
			Extractors			arguments;
			const Constant*		constant;
			const Function*		function;
			string				name;
			Float64				number;

			switch (lexer.getType ())
			{
				case Lexer::IDENTIFIER:
					name = lexer.getCurrent ();

					lexer.next ();

					if (lexer.getType () == Lexer::PARENTHESIS_BEGIN)
					{
						function = 0;

						for (Int32u i = 0; Function::functions[i].name; ++i)
						{
							if (Function::functions[i].name == name)
							{
								function = &Function::functions[i];

								break;
							}
						}

						if (!function)
							return this->fail (lexer, string ("unknown function name '") + lexer.getCurrent () + "'");

						lexer.next ();

						while (lexer.getType () != Lexer::PARENTHESIS_END)
						{
							if (arguments.size () > 0 && !this->parseType (lexer, Lexer::COMMA, "argument separator"))
								return false;

							if (!this->parseExpression (lexer, lookup, slot, &argument))
								return false;

							arguments.push_back (argument);
						}

						lexer.next ();

						if (arguments.size () < function->min || (function->max > 0 && arguments.size () > function->max))
							return this->fail (lexer, "wrong number of arguments");

						*output = function->builder (arguments, slot);
					}
					else
					{
						constant = 0;

						for (Int32u i = 0; Constant::constants[i].name; ++i)
						{
							if (Constant::constants[i].name == name)
							{
								constant = &Constant::constants[i];

								break;
							}
						}

						if (constant)
							*output = new ConstantExtractor (constant->value);
						else
							*output = new FieldExtractor (lookup.store (name));
					}

					break;

				case Lexer::NUMBER:
					if (!Convert::toFloat (&number, lexer.getCurrent ().data (), lexer.getCurrent ().length ()))
						return this->fail (lexer, "invalid number");

					*output = new ConstantExtractor (Variant (number));

					lexer.next ();

					break;

				case Lexer::STRING:
					*output = new ConstantExtractor (Variant (lexer.getCurrent ()));

					lexer.next ();

					break;

				default:
					this->fail (lexer, "unexpected character");

					return false;
			}

			this->extractors.push_back (*output);

			return true;
		}