2 * ExpressionParser.cpp - TaskJuggler
4 * Copyright (c) 2001, 2002, 2003, 2004 by Chris Schlaeger <cs@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
13 #include "ExpressionParser.h"
15 #include "Operation.h"
17 #include "ExpressionTree.h"
18 #include "tjlib-internal.h"
19 #include "ExpressionFunctionTable.h"
22 ExpressionParser::parse()
28 op = parseLogicalExpression(0);
29 if (!tokenizer.close())
39 ExpressionParser::parseLogicalExpression(int precedence)
45 tt = tokenizer.nextToken(token);
47 qDebug("parseLogicalExpression(%d): %s", precedence, token.latin1());
48 if (tt == ID || tt == ABSOLUTE_ID)
51 if ((tt = tokenizer.nextToken(lookAhead)) == LBRACKET)
53 if (EFT.isKnownFunction(token))
55 if ((op = parseFunctionCall(token)) == 0)
58 qDebug("exit after function call");
64 errorMessage(i18n("Function '%1' is unknown").arg(token));
70 tokenizer.returnToken(tt, lookAhead);
71 /* We can't test here, whether the ID is known or not. So this has
72 * to be checked at evaluation time. */
73 op = new Operation(Operation::Id, token);
76 else if (tt == STRING)
78 op = new Operation(Operation::String, token);
83 if ((date = date2time(token)) == 0)
85 errorMessage(getUtilityError());
89 op = new Operation(Operation::Date, date);
91 else if (tt == INTEGER)
93 op = new Operation(token.toLong());
97 if ((op = parseLogicalExpression(1)) == 0)
100 qDebug("exit after NOT");
103 op = new Operation(op, Operation::Not);
105 else if (tt == LBRACKET)
107 if ((op = parseLogicalExpression(0)) == 0)
110 qDebug("exit after ()");
113 if ((tt = tokenizer.nextToken(token)) != RBRACKET)
115 errorMessage(i18n("')' expected"));
122 errorMessage(i18n("Logical expression expected"));
128 tt = tokenizer.nextToken(token);
130 qDebug("Second operator %s", token.latin1());
133 Operation* op2 = parseLogicalExpression(0);
134 op = new Operation(op, Operation::And, op2);
138 Operation* op2 = parseLogicalExpression(0);
139 op = new Operation(op, Operation::Or, op2);
141 else if (tt == GREATER)
143 Operation* op2 = parseLogicalExpression(0);
144 op = new Operation(op, Operation::Greater, op2);
146 else if (tt == SMALLER)
148 Operation* op2 = parseLogicalExpression(0);
149 op = new Operation(op, Operation::Smaller, op2);
151 else if (tt == EQUAL)
153 Operation* op2 = parseLogicalExpression(0);
154 op = new Operation(op, Operation::Equal, op2);
156 else if (tt == GREATEROREQUAL)
158 Operation* op2 = parseLogicalExpression(0);
159 op = new Operation(op, Operation::GreaterOrEqual, op2);
161 else if (tt == SMALLEROREQUAL)
163 Operation* op2 = parseLogicalExpression(0);
164 op = new Operation(op, Operation::SmallerOrEqual, op2);
167 tokenizer.returnToken(tt, token);
171 qDebug("exit default");
176 ExpressionParser::parseFunctionCall(const QString& name)
181 QPtrList<Operation> args;
182 for (int i = 0; i < EFT.getArgumentCount(name); i++)
185 qDebug("Reading function '%s' arg %d", name.latin1(), i);
187 if ((op = parseLogicalExpression(0)) == 0)
190 if ((i < EFT.getArgumentCount(name) - 1) &&
191 tokenizer.nextToken(token) != COMMA)
193 errorMessage(i18n("Comma expected. "
194 "Function '%1' needs %2 arguments.")
195 .arg(name).arg(EFT.getArgumentCount(name)));
199 if ((tt = tokenizer.nextToken(token)) != RBRACKET)
201 errorMessage(i18n("')' expected"));
204 Operation** argsArr = new Operation*[args.count()];
206 for (QPtrListIterator<Operation> oli(args); *oli != 0; ++oli)
209 qDebug("function '%s' done", name.latin1());
210 return new Operation(name, argsArr, args.count());
214 ExpressionParser::errorMessage(const QString& msg)
216 tokenizer.errorMessage(msg);