File indexing completed on 2024-12-08 03:32:04
0001 /* 0002 SPDX-FileCopyrightText: 2003-2006 Cies Breijs <cies AT kde DOT nl> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "parser.h" 0008 0009 #include <QDebug> 0010 0011 #include <KLocalizedString> 0012 0013 0014 Parser::~Parser() 0015 { 0016 } 0017 0018 void Parser::initialize(Tokenizer* _tokenizer, ErrorList* _errorList) 0019 { 0020 tokenizer = _tokenizer; 0021 errorList = _errorList; 0022 0023 rootNode = new TreeNode(new Token(Token::Root, QStringLiteral("root"), 0, 0, 0, 0)); 0024 currentScope = rootNode; 0025 newScope = nullptr; 0026 finished = false; 0027 0028 nextToken(); 0029 } 0030 0031 void Parser::parse() 0032 { 0033 if (finished) return; 0034 0035 // //qDebug() << "Parser::parse() -- main parse loop called"; 0036 TreeNode* resultNode = parseStatement(); // parse the next statement 0037 if (resultNode == nullptr) { // no statement was found 0038 addError(i18n("Expected a command, instead got '%1'", currentToken->look()), *currentToken, 0); 0039 return; 0040 } 0041 0042 if (resultNode->token()->type() == Token::ScopeClose || 0043 resultNode->token()->type() == Token::EndOfInput) { 0044 delete resultNode; 0045 } else { 0046 currentScope->appendChild(resultNode); 0047 } 0048 0049 if (newScope != nullptr) { 0050 currentScope = newScope; 0051 newScope = nullptr; 0052 } 0053 } 0054 0055 void Parser::nextToken() 0056 { 0057 // get the next relevant token, and store it in currentToken 0058 0059 // skip spaces and comments: 0060 currentToken = tokenizer->getToken(); 0061 // //qDebug() << "########### got token: " << currentToken->look(); 0062 0063 while (currentToken->type() == Token::WhiteSpace || 0064 currentToken->type() == Token::Comment) { 0065 delete currentToken; 0066 currentToken = tokenizer->getToken(); 0067 // //qDebug() << "########### got token: " << currentToken->look(); 0068 } 0069 0070 if (currentToken->type() == Token::Error) 0071 addError(i18n("Could not understand '%1'", currentToken->look()), *currentToken, 100); 0072 0073 // QString out = QString("Parser::nextToken(): \"%5\" [%6] @ (%1,%2)-(%3,%4)") 0074 // .arg(currentToken->startRow()) 0075 // .arg(currentToken->startCol()) 0076 // .arg(currentToken->endRow()) 0077 // .arg(currentToken->endCol()) 0078 // .arg(currentToken->look()) 0079 // .arg(currentToken->type()); 0080 // //qDebug() << "Parser::nextToken():" << currentToken->look() << " [" << currentToken->type() << "] on line" << currentToken->startRow(); 0081 if (currentToken->type() == Token::EndOfInput) 0082 finished = true; 0083 } 0084 0085 0086 bool Parser::skipToken(int expectedTokenType) 0087 { 0088 // if the expectedTokenType matches the currentToken's type, dispose the currentToken and get a new one 0089 if (currentToken->type() == expectedTokenType) { 0090 delete currentToken; 0091 nextToken(); 0092 return true; 0093 } 0094 return false; 0095 } 0096 0097 bool Parser::skipToken(int expectedTokenType, Token& byToken) 0098 { 0099 // TODO have byToken, and "errorHappenedHereToken" 0100 //TODO: Translate the following QStrings? 0101 0102 if (skipToken(expectedTokenType)) return true; 0103 0104 switch (expectedTokenType) { 0105 case Token::ArgumentSeparator: 0106 addError(i18n("A comma was expected here..."), byToken, 0); 0107 break; 0108 case Token::EndOfInput: 0109 addError(i18n("Did not expect '%1', instead expected the line to end after %2", 0110 currentToken->look(), 0111 byToken.look()), 0112 byToken, 0); 0113 break; 0114 case Token::Assign: 0115 addError(i18n("Expected an assignment, '=', after the variable '%1'", 0116 byToken.look()), byToken, 0); 0117 break; 0118 case Token::ParenthesisClose: 0119 addError(i18n("Did not expect '%1', instead expected a closing parenthesis, ')'", 0120 currentToken->look()), byToken, 0); 0121 break; 0122 case Token::To: 0123 addError(i18n("Expected 'to' after 'for'"), byToken, 0); 0124 break; 0125 case Token::FunctionCall: 0126 addError(i18n("Expected a name for a command after 'learn' command"), byToken, 0); 0127 break; 0128 } 0129 0130 return false; 0131 } 0132 0133 0134 void Parser::addError(const QString& s, const Token& t, int code) 0135 { 0136 // if (m_testing) 0137 // //qDebug() << "ERR> " << qPrintable(s) << " (parse error)"; 0138 errorList->addError(s, t, code); 0139 } 0140 0141 void Parser::printTree() const 0142 { 0143 const char* prefix = m_testing ? "NTR> " : ""; 0144 const auto str{rootNode->toString().split(QLatin1Char('\n'), Qt::SkipEmptyParts)}; 0145 for (const QString &line : str) { 0146 qDebug() << prefix << qPrintable(line.trimmed()); 0147 } 0148 } 0149 0150 0151 0152 TreeNode* Parser::parseStatement() 0153 { 0154 // in addition to whitespace and comments (skipped by nextToken()), also skip newlines before statements 0155 while (currentToken->type() == Token::EndOfLine) { 0156 delete currentToken; 0157 nextToken(); 0158 } 0159 0160 if (finished) 0161 return new TreeNode(currentToken); // TODO check if all scopes are closed before returning + throw error 0162 0163 switch (currentToken->type()) { 0164 0165 //BEGIN GENERATED parser_statements_cpp CODE 0166 0167 /* The code between the line that start with "//BEGIN GENERATED" and "//END GENERATED" 0168 * is generated by "generate.rb" according to the definitions specified in 0169 * "definitions.rb". Please make all changes in the "definitions.rb" file, since all 0170 * all change you make here will be overwritten the next time "generate.rb" is run. 0171 * Thanks for looking at the code! 0172 */ 0173 0174 case Token::Variable : return parseVariable(); 0175 case Token::FunctionCall : return parseFunctionCall(); 0176 case Token::ScopeOpen : return parseScopeOpen(); 0177 case Token::ScopeClose : return parseScopeClose(); 0178 case Token::Exit : return parseExit(); 0179 case Token::If : return parseIf(); 0180 case Token::Repeat : return parseRepeat(); 0181 case Token::While : return parseWhile(); 0182 case Token::For : return parseFor(); 0183 case Token::Break : return parseBreak(); 0184 case Token::Return : return parseReturn(); 0185 case Token::Wait : return parseWait(); 0186 case Token::Assert : return parseAssert(); 0187 case Token::Learn : return parseLearn(); 0188 case Token::Reset : return parseReset(); 0189 case Token::Clear : return parseClear(); 0190 case Token::Center : return parseCenter(); 0191 case Token::Go : return parseGo(); 0192 case Token::GoX : return parseGoX(); 0193 case Token::GoY : return parseGoY(); 0194 case Token::Forward : return parseForward(); 0195 case Token::Backward : return parseBackward(); 0196 case Token::Direction : return parseDirection(); 0197 case Token::TurnLeft : return parseTurnLeft(); 0198 case Token::TurnRight : return parseTurnRight(); 0199 case Token::PenWidth : return parsePenWidth(); 0200 case Token::PenUp : return parsePenUp(); 0201 case Token::PenDown : return parsePenDown(); 0202 case Token::PenColor : return parsePenColor(); 0203 case Token::CanvasColor : return parseCanvasColor(); 0204 case Token::CanvasSize : return parseCanvasSize(); 0205 case Token::SpriteShow : return parseSpriteShow(); 0206 case Token::SpriteHide : return parseSpriteHide(); 0207 case Token::Print : return parsePrint(); 0208 case Token::FontSize : return parseFontSize(); 0209 case Token::Random : return parseRandom(); 0210 case Token::GetX : return parseGetX(); 0211 case Token::GetY : return parseGetY(); 0212 case Token::Message : return parseMessage(); 0213 case Token::Ask : return parseAsk(); 0214 case Token::Pi : return parsePi(); 0215 case Token::Tan : return parseTan(); 0216 case Token::Sin : return parseSin(); 0217 case Token::Cos : return parseCos(); 0218 case Token::ArcTan : return parseArcTan(); 0219 case Token::ArcSin : return parseArcSin(); 0220 case Token::ArcCos : return parseArcCos(); 0221 case Token::Sqrt : return parseSqrt(); 0222 case Token::Round : return parseRound(); 0223 case Token::GetDirection : return parseGetDirection(); 0224 case Token::Mod : return parseMod(); 0225 0226 //END GENERATED parser_statements_cpp CODE 0227 case Token::Error : return new TreeNode(currentToken); 0228 default : { 0229 //Token type is something else... 0230 ////qDebug() << "Parser::parseStatement(): I don't know this Token type."; 0231 ////qDebug() << "Look: " << currentToken->look() << " type: " << currentToken->type(); 0232 addError(i18n("You cannot put '%1' here.", currentToken->look()), *currentToken, 0); 0233 finished = true; 0234 return new TreeNode(currentToken); 0235 } 0236 } 0237 } 0238 0239 0240 TreeNode* Parser::parseFactor() 0241 { 0242 // //qDebug() << "Parser::parseFactor()"; 0243 Token* rememberedToken; 0244 TreeNode* node; 0245 switch (currentToken->type()) { 0246 case Token::ParenthesisOpen: 0247 rememberedToken = currentToken; 0248 nextToken(); 0249 node = parseExpression(); 0250 skipToken(Token::ParenthesisClose, *rememberedToken); 0251 break; 0252 0253 case Token::FunctionCall: 0254 node = parseFunctionCall(); 0255 break; 0256 0257 case Token::Variable: 0258 node = new TreeNode(currentToken); 0259 nextToken(); 0260 break; 0261 0262 case Token::String: 0263 node = new TreeNode(currentToken); 0264 { // extra scope to localize the QString 'str' 0265 QString str = currentToken->look(); 0266 if (!currentToken->look().endsWith(QLatin1Char('\"'))) { 0267 str += QLatin1String("\""); 0268 addError(i18n("Text string was not properly closed, expected a double quote, ' \" ', to close the string."), *currentToken, 0); 0269 } 0270 node->value()->setString(str.mid(1, str.length() - 2)); 0271 } 0272 nextToken(); 0273 break; 0274 0275 case Token::Number: 0276 node = new TreeNode(currentToken); 0277 { 0278 bool ok = true; 0279 double num = currentToken->look().toDouble(&ok); 0280 if (ok) { 0281 node->value()->setNumber(num); 0282 nextToken(); 0283 } else { 0284 qCritical("Parser::parseFactor(): could not parse a number"); 0285 } 0286 } 0287 break; 0288 0289 case Token::True: 0290 node = new TreeNode(currentToken); 0291 node->value()->setBool(true); 0292 nextToken(); 0293 break; 0294 0295 case Token::False: 0296 node = new TreeNode(currentToken); 0297 node->value()->setBool(false); 0298 nextToken(); 0299 break; 0300 0301 // case Token::Run: 0302 // node = ExternalRun(); 0303 // break; 0304 // 0305 // case tokInputWindow: 0306 // node = InputWindow(); 0307 // break; 0308 // 0309 // case tokRandom: 0310 // node = Random(); 0311 // break; 0312 // 0313 // case Token::EndOfLine: 0314 // node = new TreeNode(currentToken); 0315 // break; 0316 0317 0318 default: 0319 // TODO maybe precheck if this is a statement that returns something 0320 node = parseStatement(); 0321 break; 0322 0323 0324 // default: 0325 // QString s = currentToken->look(); 0326 // if ( s.isEmpty() || currentToken->type() == Token::EndOfInput ) 0327 // { 0328 // // Error(currentToken, i18n("INTERNAL ERROR NR %1: please sent this Logo script to KTurtle developers").arg(1), 1020); 0329 // // if this error occurs the see the Parser::Repeat for the good solution using 'preservedToken' 0330 // } 0331 // else 0332 // { 0333 // // Error(currentToken, i18n("Cannot understand '%1', expected an expression after the '%2' command").arg(s).arg(preservedToken->look()), 1020); 0334 // } 0335 // node = new TreeNode(currentToken); 0336 // nextToken(); 0337 // break; 0338 } 0339 return node; 0340 } 0341 0342 0343 TreeNode* Parser::parseSignedFactor() 0344 { 0345 // //qDebug() << "Parser::parseSignedFactor()"; 0346 // see if there is a plus, minus or 'not' in front of a factor 0347 Token* rememberedToken; 0348 TreeNode* node; 0349 switch (currentToken->type()) { 0350 case Token::Addition: 0351 nextToken(); 0352 return parseFactor(); 0353 break; 0354 0355 case Token::Subtraction: 0356 rememberedToken = currentToken; 0357 nextToken(); 0358 node = parseFactor(); 0359 if (node->token()->type() == Token::Number) { 0360 // in case of just a constant (-3) situation 0361 node->value()->setNumber(-1 * node->value()->number()); 0362 return node; 0363 } else { 0364 // in case of a variable or other situation (-$a) 0365 TreeNode* minusNode = new TreeNode(rememberedToken); 0366 minusNode->appendChild(node); 0367 return minusNode; 0368 } 0369 break; 0370 0371 case Token::Not: 0372 rememberedToken = currentToken; 0373 nextToken(); 0374 node = parseFactor(); 0375 { // extra scope needed to localize not_Node 0376 TreeNode* notNode = new TreeNode(rememberedToken); 0377 notNode->appendChild(node); 0378 return notNode; 0379 } 0380 break; 0381 0382 default: 0383 // no 'sign', no problem; just had to check if there was any... continue with the real work: 0384 return parseFactor(); 0385 break; 0386 } 0387 } 0388 0389 0390 0391 TreeNode* Parser::parseTerm() 0392 { 0393 // //qDebug() << "Parser::parseTerm()"; 0394 TreeNode* termNode = parseSignedFactor(); 0395 TreeNode* pos = termNode; 0396 TreeNode* left = nullptr; 0397 TreeNode* right = nullptr; 0398 0399 while ( (currentToken->type() == Token::Multiplication) || 0400 (currentToken->type() == Token::Division) || 0401 (currentToken->type() == Token::Power) ) { 0402 // while we find a multiplicative operator do... 0403 left = pos; 0404 pos = new TreeNode(currentToken); 0405 pos->appendChild(left); 0406 nextToken(); 0407 right = parseSignedFactor(); 0408 if (right != nullptr) 0409 pos->appendChild(right); 0410 termNode = pos; 0411 } 0412 return termNode; 0413 } 0414 0415 0416 TreeNode* Parser::parseExpression() 0417 { 0418 // //qDebug() << "Parser::parseExpression()"; 0419 TreeNode* expressionNode = parseTerm(); 0420 TreeNode* pos = expressionNode; 0421 TreeNode* left = nullptr; 0422 TreeNode* right = nullptr; 0423 0424 Token* prevToken = nullptr; 0425 0426 while ((currentToken->type() == Token::Addition) || 0427 (currentToken->type() == Token::Subtraction) || 0428 (currentToken->type() == Token::GreaterThan) || 0429 (currentToken->type() == Token::GreaterOrEquals) || 0430 (currentToken->type() == Token::LessThan) || 0431 (currentToken->type() == Token::LessOrEquals) || 0432 (currentToken->type() == Token::Equals) || 0433 (currentToken->type() == Token::NotEquals) || 0434 (currentToken->type() == Token::Or) || 0435 (currentToken->type() == Token::And)) { 0436 left = pos; 0437 pos = new TreeNode(currentToken); 0438 pos->appendChild(left); 0439 prevToken = currentToken; 0440 nextToken(); 0441 0442 if(prevToken->type() == Token::And || 0443 prevToken->type() == Token::Or) 0444 right = parseExpression(); 0445 else 0446 right = parseTerm(); 0447 if (right != nullptr) pos->appendChild(right); 0448 expressionNode = pos; 0449 } 0450 return expressionNode; 0451 } 0452 0453 0454 0455 void Parser::appendArguments(TreeNode* node) 0456 { 0457 // appends the nodes of arguments to the node, does not do any type/quantity checking. 0458 // this because it's also used for the user defined 'functionCall' where we don't know type nor quantity 0459 // we also don't know if this node is (part of) an argument itself 0460 if (currentToken->type() == Token::EndOfLine || 0461 currentToken->type() == Token::EndOfInput || 0462 currentToken->type() == Token::ArgumentSeparator || 0463 currentToken->type() == Token::ParenthesisClose || 0464 currentToken->type() == Token::ScopeOpen || 0465 currentToken->type() == Token::ScopeClose) return; 0466 node->appendChild(parseExpression()); // append the first parameter 0467 while (skipToken(Token::ArgumentSeparator)) { // pushes through the comma 0468 if (currentToken->type() == Token::EndOfLine || 0469 currentToken->type() == Token::EndOfInput) 0470 return; // catch forgotten expressions (go 10,) 0471 node->appendChild(parseExpression()); 0472 } 0473 } 0474 0475 0476 0477 //BEGIN GENERATED parser_cpp CODE 0478 0479 /* The code between the line that start with "//BEGIN GENERATED" and "//END GENERATED" 0480 * is generated by "generate.rb" according to the definitions specified in 0481 * "definitions.rb". Please make all changes in the "definitions.rb" file, since all 0482 * all change you make here will be overwritten the next time "generate.rb" is run. 0483 * Thanks for looking at the code! 0484 */ 0485 0486 TreeNode* Parser::parseVariable() { 0487 // This is called to the variable is the first token on a line. 0488 // There has to be an assignment token right after it... 0489 TreeNode* variableNode = new TreeNode(currentToken); 0490 nextToken(); 0491 Token* remeberedToken = new Token(*currentToken); 0492 skipToken(Token::Assign, *variableNode->token()); 0493 TreeNode* assignNode = new TreeNode(remeberedToken); 0494 assignNode->appendChild(variableNode); // the LHV; the symbol 0495 assignNode->appendChild(parseExpression()); // the RHV; the expression 0496 return assignNode; 0497 } 0498 0499 TreeNode* Parser::parseFunctionCall() { 0500 TreeNode* node = new TreeNode(currentToken); 0501 node->token()->setType(Token::FunctionCall); 0502 nextToken(); 0503 appendArguments(node); 0504 return node; 0505 } 0506 TreeNode* Parser::parseScopeOpen() { 0507 0508 TreeNode* scopeNode = new TreeNode(new Token(Token::Scope, QStringLiteral("{...}"), currentToken->startRow(), currentToken->startCol(), 0, 0)); 0509 delete currentToken; 0510 nextToken(); 0511 // cannot change the currentScope to this scope cauz we still have to work in the currentScope 0512 // so we set the newScope, which the currentScope will become after parsing the current statement 0513 newScope = scopeNode; 0514 return scopeNode; 0515 } 0516 TreeNode* Parser::parseScopeClose() { 0517 0518 TreeNode* node = new TreeNode(currentToken); 0519 int endRow = currentToken->endRow(); 0520 int endCol = currentToken->endCol(); 0521 nextToken(); 0522 while (currentToken->type() == Token::EndOfLine) { // allow newlines before else 0523 delete currentToken; 0524 nextToken(); 0525 } 0526 if (currentScope->parent() && 0527 currentScope->parent()->token()->type() == Token::If && 0528 currentToken->type() == Token::Else) { 0529 currentScope->parent()->appendChild(parseElse()); 0530 } 0531 if (currentScope != rootNode) { 0532 // find the parent scope of this scope, and make it current 0533 TreeNode* parentScope = currentScope; 0534 do { 0535 parentScope = parentScope->parent(); 0536 } while (parentScope != rootNode && parentScope->token()->type() != Token::Scope); 0537 currentScope->token()->setEndRow(endRow); 0538 currentScope->token()->setEndCol(endCol); 0539 currentScope = parentScope; 0540 } 0541 return node; 0542 } 0543 TreeNode* Parser::parseExit() { 0544 0545 TreeNode* node = new TreeNode(currentToken); 0546 nextToken(); 0547 skipToken(Token::EndOfLine, *node->token()); 0548 return node; 0549 } 0550 TreeNode* Parser::parseIf() { 0551 0552 TreeNode* node = new TreeNode(currentToken); 0553 nextToken(); 0554 node->appendChild(parseExpression()); 0555 if (currentToken->type() == Token::ScopeOpen) { 0556 node->appendChild(parseScopeOpen()); // if followed by a scope 0557 } 0558 return node; 0559 } 0560 TreeNode* Parser::parseElse() { 0561 0562 nextToken(); 0563 if (currentToken->type() == Token::ScopeOpen) { 0564 return parseScopeOpen(); // if followed by a scope 0565 } 0566 return parseStatement(); // if followed by single statement 0567 } 0568 TreeNode* Parser::parseRepeat() { 0569 0570 TreeNode* node = new TreeNode(currentToken); 0571 nextToken(); 0572 node->appendChild(parseExpression()); 0573 if (currentToken->type() == Token::ScopeOpen) { 0574 node->appendChild(parseScopeOpen()); // if followed by a scope 0575 } else { 0576 node->appendChild(parseStatement()); // if followed by single statement 0577 } 0578 return node; 0579 } 0580 TreeNode* Parser::parseWhile() { 0581 0582 TreeNode* node = new TreeNode(currentToken); 0583 nextToken(); 0584 node->appendChild(parseExpression()); 0585 if (currentToken->type() == Token::ScopeOpen) { 0586 node->appendChild(parseScopeOpen()); // if followed by a scope 0587 } else { 0588 node->appendChild(parseStatement()); // if followed by single statement 0589 } 0590 return node; 0591 } 0592 TreeNode* Parser::parseFor() { 0593 0594 TreeNode* node = new TreeNode(currentToken); 0595 nextToken(); 0596 Token* firstToken = currentToken; 0597 nextToken(); 0598 if (firstToken->type() == Token::Variable && currentToken->type() == Token::Assign) { 0599 node->token()->setType(Token::ForTo); 0600 node->appendChild(new TreeNode(firstToken)); 0601 nextToken(); 0602 node->appendChild(parseExpression()); 0603 skipToken(Token::To, *node->token()); 0604 node->appendChild(parseExpression()); 0605 if (currentToken->type() == Token::Step) { 0606 nextToken(); 0607 node->appendChild(parseExpression()); 0608 } else { 0609 TreeNode* step = new TreeNode(new Token(Token::Number, QStringLiteral("1"), 0,0,0,0)); 0610 step->setValue(Value(1.0)); 0611 node->appendChild(step); 0612 } 0613 // } else if (currentToken->type() == Token::In) { 0614 // // @TODO something for a for-in loop 0615 } else { 0616 addError(i18n("'for' was called wrongly"), *node->token(), 0); 0617 finished = true; // abort after this error 0618 return node; 0619 } 0620 0621 if (currentToken->type() == Token::ScopeOpen) { 0622 node->appendChild(parseScopeOpen()); // if followed by a scope 0623 } else { 0624 node->appendChild(parseStatement()); // if followed by single statement 0625 } 0626 0627 return node; 0628 } 0629 TreeNode* Parser::parseBreak() { 0630 0631 TreeNode* node = new TreeNode(currentToken); 0632 nextToken(); 0633 skipToken(Token::EndOfLine, *node->token()); 0634 return node; 0635 } 0636 TreeNode* Parser::parseReturn() { 0637 0638 TreeNode* node = new TreeNode(currentToken); 0639 nextToken(); 0640 appendArguments(node); 0641 skipToken(Token::EndOfLine, *node->token()); 0642 return node; 0643 } 0644 TreeNode* Parser::parseWait() { 0645 0646 TreeNode* node = new TreeNode(currentToken); 0647 nextToken(); 0648 appendArguments(node); 0649 skipToken(Token::EndOfLine, *node->token()); 0650 return node; 0651 } 0652 TreeNode* Parser::parseAssert() { 0653 0654 TreeNode* node = new TreeNode(currentToken); 0655 nextToken(); 0656 appendArguments(node); 0657 skipToken(Token::EndOfLine, *node->token()); 0658 return node; 0659 } 0660 TreeNode* Parser::parseLearn() { 0661 0662 TreeNode* node = new TreeNode(currentToken); 0663 nextToken(); 0664 node->appendChild(new TreeNode(new Token(*currentToken))); 0665 skipToken(Token::FunctionCall, *node->token()); 0666 0667 TreeNode* argumentList = new TreeNode(new Token(Token::ArgumentList, QStringLiteral("arguments"), 0, 0, 0, 0)); 0668 while (currentToken->type() == Token::Variable) { 0669 // cannot just call appendArguments here because we're only appending Token::Variable tokens 0670 argumentList->appendChild(new TreeNode(currentToken)); 0671 nextToken(); 0672 if (currentToken->type() != Token::ArgumentSeparator) break; 0673 nextToken(); 0674 } 0675 node->appendChild(argumentList); 0676 0677 //Skip all the following EndOfLine's 0678 while (currentToken->type() == Token::EndOfLine) { 0679 delete currentToken; 0680 nextToken(); 0681 } 0682 0683 if (currentToken->type() == Token::ScopeOpen) { 0684 node->appendChild(parseScopeOpen()); // if followed by a scope 0685 } else { 0686 addError(i18n("Expected a scope after the 'learn' command"), *node->token(), 0); 0687 } 0688 return node; 0689 } 0690 TreeNode* Parser::parseReset() { 0691 0692 TreeNode* node = new TreeNode(currentToken); 0693 nextToken(); 0694 skipToken(Token::EndOfLine, *node->token()); 0695 return node; 0696 } 0697 TreeNode* Parser::parseClear() { 0698 0699 TreeNode* node = new TreeNode(currentToken); 0700 nextToken(); 0701 skipToken(Token::EndOfLine, *node->token()); 0702 return node; 0703 } 0704 TreeNode* Parser::parseCenter() { 0705 0706 TreeNode* node = new TreeNode(currentToken); 0707 nextToken(); 0708 skipToken(Token::EndOfLine, *node->token()); 0709 return node; 0710 } 0711 TreeNode* Parser::parseGo() { 0712 0713 TreeNode* node = new TreeNode(currentToken); 0714 nextToken(); 0715 appendArguments(node); 0716 skipToken(Token::EndOfLine, *node->token()); 0717 return node; 0718 } 0719 TreeNode* Parser::parseGoX() { 0720 0721 TreeNode* node = new TreeNode(currentToken); 0722 nextToken(); 0723 appendArguments(node); 0724 skipToken(Token::EndOfLine, *node->token()); 0725 return node; 0726 } 0727 TreeNode* Parser::parseGoY() { 0728 0729 TreeNode* node = new TreeNode(currentToken); 0730 nextToken(); 0731 appendArguments(node); 0732 skipToken(Token::EndOfLine, *node->token()); 0733 return node; 0734 } 0735 TreeNode* Parser::parseForward() { 0736 0737 TreeNode* node = new TreeNode(currentToken); 0738 nextToken(); 0739 appendArguments(node); 0740 skipToken(Token::EndOfLine, *node->token()); 0741 return node; 0742 } 0743 TreeNode* Parser::parseBackward() { 0744 0745 TreeNode* node = new TreeNode(currentToken); 0746 nextToken(); 0747 appendArguments(node); 0748 skipToken(Token::EndOfLine, *node->token()); 0749 return node; 0750 } 0751 TreeNode* Parser::parseDirection() { 0752 0753 TreeNode* node = new TreeNode(currentToken); 0754 nextToken(); 0755 appendArguments(node); 0756 skipToken(Token::EndOfLine, *node->token()); 0757 return node; 0758 } 0759 TreeNode* Parser::parseTurnLeft() { 0760 0761 TreeNode* node = new TreeNode(currentToken); 0762 nextToken(); 0763 appendArguments(node); 0764 skipToken(Token::EndOfLine, *node->token()); 0765 return node; 0766 } 0767 TreeNode* Parser::parseTurnRight() { 0768 0769 TreeNode* node = new TreeNode(currentToken); 0770 nextToken(); 0771 appendArguments(node); 0772 skipToken(Token::EndOfLine, *node->token()); 0773 return node; 0774 } 0775 TreeNode* Parser::parsePenWidth() { 0776 0777 TreeNode* node = new TreeNode(currentToken); 0778 nextToken(); 0779 appendArguments(node); 0780 skipToken(Token::EndOfLine, *node->token()); 0781 return node; 0782 } 0783 TreeNode* Parser::parsePenUp() { 0784 0785 TreeNode* node = new TreeNode(currentToken); 0786 nextToken(); 0787 skipToken(Token::EndOfLine, *node->token()); 0788 return node; 0789 } 0790 TreeNode* Parser::parsePenDown() { 0791 0792 TreeNode* node = new TreeNode(currentToken); 0793 nextToken(); 0794 skipToken(Token::EndOfLine, *node->token()); 0795 return node; 0796 } 0797 TreeNode* Parser::parsePenColor() { 0798 0799 TreeNode* node = new TreeNode(currentToken); 0800 nextToken(); 0801 appendArguments(node); 0802 skipToken(Token::EndOfLine, *node->token()); 0803 return node; 0804 } 0805 0806 TreeNode* Parser::parseCanvasColor() { 0807 TreeNode* node = new TreeNode(currentToken); 0808 nextToken(); 0809 appendArguments(node); 0810 skipToken(Token::EndOfLine, *node->token()); 0811 return node; 0812 } 0813 0814 TreeNode* Parser::parseCanvasSize() { 0815 TreeNode* node = new TreeNode(currentToken); 0816 nextToken(); 0817 appendArguments(node); 0818 skipToken(Token::EndOfLine, *node->token()); 0819 return node; 0820 } 0821 0822 TreeNode* Parser::parseSpriteShow() { 0823 TreeNode* node = new TreeNode(currentToken); 0824 nextToken(); 0825 skipToken(Token::EndOfLine, *node->token()); 0826 return node; 0827 } 0828 TreeNode* Parser::parseSpriteHide() { 0829 0830 TreeNode* node = new TreeNode(currentToken); 0831 nextToken(); 0832 skipToken(Token::EndOfLine, *node->token()); 0833 return node; 0834 } 0835 TreeNode* Parser::parsePrint() { 0836 0837 TreeNode* node = new TreeNode(currentToken); 0838 nextToken(); 0839 appendArguments(node); 0840 skipToken(Token::EndOfLine, *node->token()); 0841 return node; 0842 } 0843 TreeNode* Parser::parseFontSize() { 0844 0845 TreeNode* node = new TreeNode(currentToken); 0846 nextToken(); 0847 appendArguments(node); 0848 skipToken(Token::EndOfLine, *node->token()); 0849 return node; 0850 } 0851 TreeNode* Parser::parseRandom() { 0852 0853 TreeNode* node = new TreeNode(currentToken); 0854 nextToken(); 0855 appendArguments(node); 0856 skipToken(Token::EndOfLine, *node->token()); 0857 return node; 0858 } 0859 TreeNode* Parser::parseGetX() { 0860 0861 TreeNode* node = new TreeNode(currentToken); 0862 nextToken(); 0863 skipToken(Token::EndOfLine, *node->token()); 0864 return node; 0865 } 0866 TreeNode* Parser::parseGetY() { 0867 0868 TreeNode* node = new TreeNode(currentToken); 0869 nextToken(); 0870 skipToken(Token::EndOfLine, *node->token()); 0871 return node; 0872 } 0873 TreeNode* Parser::parseMessage() { 0874 0875 TreeNode* node = new TreeNode(currentToken); 0876 nextToken(); 0877 appendArguments(node); 0878 skipToken(Token::EndOfLine, *node->token()); 0879 return node; 0880 } 0881 TreeNode* Parser::parseAsk() { 0882 0883 TreeNode* node = new TreeNode(currentToken); 0884 nextToken(); 0885 appendArguments(node); 0886 skipToken(Token::EndOfLine, *node->token()); 0887 return node; 0888 } 0889 TreeNode* Parser::parsePi() { 0890 0891 TreeNode* node = new TreeNode(currentToken); 0892 nextToken(); 0893 skipToken(Token::EndOfLine, *node->token()); 0894 return node; 0895 } 0896 TreeNode* Parser::parseTan() { 0897 0898 TreeNode* node = new TreeNode(currentToken); 0899 nextToken(); 0900 appendArguments(node); 0901 skipToken(Token::EndOfLine, *node->token()); 0902 return node; 0903 } 0904 TreeNode* Parser::parseSin() { 0905 0906 TreeNode* node = new TreeNode(currentToken); 0907 nextToken(); 0908 appendArguments(node); 0909 skipToken(Token::EndOfLine, *node->token()); 0910 return node; 0911 } 0912 TreeNode* Parser::parseCos() { 0913 0914 TreeNode* node = new TreeNode(currentToken); 0915 nextToken(); 0916 appendArguments(node); 0917 skipToken(Token::EndOfLine, *node->token()); 0918 return node; 0919 } 0920 TreeNode* Parser::parseArcTan() { 0921 0922 TreeNode* node = new TreeNode(currentToken); 0923 nextToken(); 0924 appendArguments(node); 0925 skipToken(Token::EndOfLine, *node->token()); 0926 return node; 0927 } 0928 TreeNode* Parser::parseArcSin() { 0929 0930 TreeNode* node = new TreeNode(currentToken); 0931 nextToken(); 0932 appendArguments(node); 0933 skipToken(Token::EndOfLine, *node->token()); 0934 return node; 0935 } 0936 TreeNode* Parser::parseArcCos() { 0937 0938 TreeNode* node = new TreeNode(currentToken); 0939 nextToken(); 0940 appendArguments(node); 0941 skipToken(Token::EndOfLine, *node->token()); 0942 return node; 0943 } 0944 TreeNode* Parser::parseSqrt() { 0945 0946 TreeNode* node = new TreeNode(currentToken); 0947 nextToken(); 0948 appendArguments(node); 0949 skipToken(Token::EndOfLine, *node->token()); 0950 return node; 0951 } 0952 TreeNode* Parser::parseRound() { 0953 0954 TreeNode* node = new TreeNode(currentToken); 0955 nextToken(); 0956 appendArguments(node); 0957 skipToken(Token::EndOfLine, *node->token()); 0958 return node; 0959 } 0960 TreeNode* Parser::parseGetDirection() { 0961 0962 TreeNode* node = new TreeNode(currentToken); 0963 nextToken(); 0964 skipToken(Token::EndOfLine, *node->token()); 0965 return node; 0966 } 0967 TreeNode* Parser::parseMod() { 0968 0969 TreeNode* node = new TreeNode(currentToken); 0970 nextToken(); 0971 appendArguments(node); 0972 skipToken(Token::EndOfLine, *node->token()); 0973 return node; 0974 } 0975 0976 //END GENERATED parser_cpp CODE 0977 0978 0979