2 Copyright (C) 2003 by Walter Schreppers
3 Copyright (C) 2004 by Cies Breijs
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of version 2 of the GNU General Public
7 License as published by the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 // This file is originally written by Walter Scheppers, but allmost
20 // allmost every aspect of it is heavily changed by Cies Breijs.
23 #include <qstringlist.h>
31 Parser::Parser(QTextIStream
& in
)
33 lexer
= new Lexer(in
);
34 tree
= new TreeNode();
44 tree
= Program(); // the first node that keeps the lexer running till finished/error
47 void Parser::getToken()
49 currentToken
= lexer
->lex(); // stores a Token, obtained though the lexer, in 'currentToken'
50 row
= currentToken
.start
.row
; // these will have to leave eventually, all should be passed on by the Token
51 col
= currentToken
.start
.col
;
52 kdDebug(0)<<"Parser::getToken(), got a token: '"<<currentToken
.look
<<"', @ ("<<currentToken
.start
.row
<<", "<<currentToken
.start
.col
<<") - ("<<currentToken
.end
.row
<<", "<<currentToken
.end
.col
<<"), tok-number:"<<currentToken
.type
<<endl
;
55 TreeNode
* Parser::Program()
58 emptyToken
.type
= tokNotSet
;
60 emptyToken
.start
.row
= 0;
61 emptyToken
.start
.col
= 0;
62 emptyToken
.end
.row
= 0;
63 emptyToken
.end
.col
= 0;
65 TreeNode
* program
= new TreeNode(emptyToken
, programNode
, "program");
66 TreeNode
* block
= new TreeNode(emptyToken
, blockNode
, "block");
70 // this is the main parse loop
71 kdDebug(0)<<"Parser::Program(): entering main parse loop..."<<endl
;
72 while (currentToken
.type
!= tokEOF
) // currentToken.type returns the type of the currentToken
74 kdDebug(0)<<"Parser::Program(), [main parse loop]: looking for next statement..."<<endl
;
75 block
->appendChild( Statement() );
76 while (currentToken
.type
== tokEOL
) getToken(); // newlines between statements are allowed
77 // runs statement related code, stores the returned TreeNode* in the nodetree
78 // note: Statement() allways gets a new Token with getToken() before it returns
80 program
->appendChild(block
);
81 kdDebug(0)<<"Parser::Program(): leaving main parse loop..."<<endl
;
86 void Parser::matchToken(int expectedToken
)
88 if (currentToken
.type
== expectedToken
)
90 getToken(); // get a new token
94 switch (expectedToken
)
97 Error(currentToken
, i18n("Unexpected intruction after the '%1' command, please use only one instuction per line").arg(preservedToken
.look
), 1010);
101 Error(preservedToken
, i18n("Expected '['"), 1010);
105 Error(currentToken
, i18n("Expected 'to' after the '%1' command").arg(preservedToken
.look
), 1010);
109 Error(currentToken
, i18n("Expected '=' after the '%1' command").arg(preservedToken
.look
), 1010);
113 Error(currentToken
, i18n("Expected ']' after the '%1' command").arg(preservedToken
.look
), 1010);
117 Error(preservedToken
, i18n("Expected a name after the '%1' command").arg(preservedToken
.look
), 1010);
121 Error(currentToken
, i18n("UNDEFINED ERROR NR %1: please sent this Logo script to the KTurtle developers").arg(expectedToken
), 1010);
127 void Parser::appendParameters(TreeNode
* node
)
129 node
->appendChild( Expression() ); // append the first papameter
130 while (currentToken
.type
== tokComma
)
132 matchToken(tokComma
); // push through the comma
133 if (currentToken
.type
== tokEOL
) return; // catch forgotten expressions, like "go 10, "
134 node
->appendChild( Expression() );
139 TreeNode
* Parser::getId()
141 TreeNode
* n
= new TreeNode(currentToken
, idNode
);
142 n
->setLook(currentToken
.look
);
143 matchToken(tokUnknown
); // Id's are ofcouse not yet known
149 TreeNode
* Parser::FunctionCall(Token maybeFunctionCall
)
151 kdDebug(0)<<"Parser::FunctionCall() [using identifier: '"<<maybeFunctionCall
.look
<<"']"<<endl
;
152 TreeNode
* fcall
= new TreeNode(maybeFunctionCall
, functionCallNode
);
154 TreeNode
* paramList
= new TreeNode(currentToken
, idListNode
, "idlist");
155 // if (currentToken.type != tokEOL && currentToken.type != tokEOF)
156 if (currentToken
.type
== tokNumber
||
157 currentToken
.type
== tokString
||
158 currentToken
.type
== tokUnknown
) // only if there is a possible parameter given after the call...
160 TreeNode
* expr
= Expression();
161 if (expr
->getType() == Unknown
) Error(currentToken
, i18n("Expected an expression"), 1020);
162 else paramList
->appendChild(expr
);
163 while (currentToken
.type
== tokComma
)
165 matchToken(tokComma
);
167 if (expr
->getType() == Unknown
) Error(currentToken
, i18n("Expected an expression"), 1020);
168 else paramList
->appendChild(expr
);
171 fcall
->appendChild(paramList
);
177 TreeNode
* Parser::Factor()
180 Token rememberedToken
= currentToken
;
181 switch (currentToken
.type
)
184 matchToken(tokBraceOpen
);
186 matchToken(tokBraceClose
);
191 if (learnedFunctionList
.contains(rememberedToken
.look
) > 0) // is function call
194 node
= FunctionCall(rememberedToken
);
195 node
->setType(funcReturnNode
); // expect returned value on stack
200 node
= new TreeNode(currentToken
, constantNode
);
201 { // extra scope to localize the QString 'str'
202 QString str
= currentToken
.look
;
203 if ( currentToken
.look
.endsWith("\"") )
205 // cut off the quotes and store the value
206 str
.remove(0, 1).truncate( currentToken
.look
.length() - 2 );
208 else // problems but we need to keep it moving
210 str
.remove(0, 1); // cut off the first quote only
211 Error(currentToken
, i18n("String text not properly delimited with a ' \" ' (double quote)"), 1060);
215 matchToken(tokString
);
219 node
= new TreeNode(currentToken
, constantNode
);
220 node
->setValue(currentToken
.value
);
221 matchToken(tokNumber
);
225 node
= ExternalRun();
229 node
= InputWindow();
237 node
= new TreeNode(currentToken
, Unknown
);
241 QString s
= currentToken
.look
;
242 if ( s
.isEmpty() || currentToken
.type
== tokEOF
)
244 Error(currentToken
, i18n("INTERNAL ERROR NR %1: please sent this Logo script to KTurtle developers").arg(1), 1020);
245 // if this error occurs the see the Parser::Repeat for the good solution using 'preservedToken'
249 Error(currentToken
, i18n("Cannot understand '%1', expected an expression after the '%2' command").arg(s
).arg(preservedToken
.look
), 1020);
251 node
= new TreeNode(currentToken
, Unknown
);
259 TreeNode
* Parser::signedFactor()
261 // see if there is a tokPlus, tokMinus or tokNot infront of the factor
263 switch (currentToken
.type
)
271 preservedToken
= currentToken
;
272 matchToken(tokMinus
);
274 if (node
->getType() == constantNode
)
276 // in case of just a constant (-3) situation
277 Value num
= node
->getValue();
278 num
.setNumber( -num
.Number() );
284 // in case of a variable or other situation (-a)
285 TreeNode
* minus
= new TreeNode(preservedToken
, minusNode
);
286 minus
->appendChild(node
);
292 preservedToken
= currentToken
;
295 { // extra scope needed to localize not_Node
296 TreeNode
* not_Node
= new TreeNode(preservedToken
, notNode
);
297 not_Node
->appendChild(node
);
303 // fall-through safety
311 TreeNode
* Parser::Term()
313 TreeNode
* termNode
= signedFactor();
314 TreeNode
* pos
= termNode
;
315 TreeNode
* left
= NULL
;
316 TreeNode
* right
= NULL
;
318 while ( (currentToken
.type
== tokMul
) || (currentToken
.type
== tokDev
) || (currentToken
.type
== tokAnd
) )
320 // while is is a multiplicative operator do...
322 pos
= new TreeNode(currentToken
, Unknown
);
323 pos
->appendChild(left
);
325 switch (currentToken
.type
)
329 right
= signedFactor();
330 pos
->setType(mulNode
);
335 right
= signedFactor();
336 pos
->setType(divNode
);
341 right
= signedFactor();
342 pos
->setType(andNode
);
346 Error(currentToken
, i18n("Expected '*' or '/'"), 1030);
351 if (right
!= NULL
) pos
->appendChild(right
);
358 bool Parser::isAddOp(Token t
)
360 return ( (t
.type
== tokPlus
) ||
361 (t
.type
== tokMinus
) ||
374 /*---------------------------------------------------------------*/
375 /* Parse and Translate an Expression */
376 TreeNode
* Parser::Expression()
378 TreeNode
* retExp
= Term(); // preset the base-TreeNode as it eventually will be returned
379 TreeNode
* pos
= retExp
;
380 TreeNode
* left
= NULL
;
381 TreeNode
* right
= NULL
;
383 while ( isAddOp(currentToken
) )
386 pos
= new TreeNode(currentToken
, Unknown
);
387 pos
->appendChild(left
);
388 switch (currentToken
.type
)
393 pos
->setType(addNode
);
397 matchToken(tokMinus
);
399 pos
->setType(subNode
);
405 pos
->setType(nodeGT
);
411 pos
->setType(nodeLT
);
417 pos
->setType(nodeGE
);
423 pos
->setType(nodeLE
);
429 pos
->setType(nodeEQ
);
435 pos
->setType(nodeNE
);
441 pos
->setType(orNode
);
445 Error(currentToken
, i18n("Expected '*' or '/'"), 1040);
450 if (right
!= NULL
) pos
->appendChild(right
);
457 TreeNode
* Parser::Assignment(Token t
)
459 TreeNode
* node
= new TreeNode(t
, assignNode
);
460 matchToken(tokAssign
); // match the '='
462 // the child is the expression or RHV of assignment
463 TreeNode
* expr
= NULL
;
464 // if (currentToken.type == tokUnknown) expr = Other(); // in case of an functioncall
465 // else expr = Expression(); -------> fuctioncalls get caught in Expression() and co.
469 node
->appendChild(expr
);
475 TreeNode
* Parser::Statement()
477 kdDebug(0)<<"Parser::Statement()"<<endl
;
478 while (currentToken
.type
== tokEOL
) getToken(); // statements can allways start on newlines
479 switch (currentToken
.type
)
481 case tokLearn
: return Learn(); break;
483 case tokIf
: return If(); break;
484 case tokFor
: return For(); break;
485 case tokForEach
: return ForEach(); break;
486 case tokWhile
: return While(); break;
487 case tokRun
: return ExternalRun(); break;
488 case tokReturn
: return Return(); break;
489 case tokBreak
: return Break(); break;
490 case tokUnknown
: return Other(); break; //assignment or function call
492 case tokClear
: return Clear(); break;
493 case tokGo
: return Go(); break;
494 case tokGoX
: return GoX(); break;
495 case tokGoY
: return GoY(); break;
496 case tokForward
: return Forward(); break;
497 case tokBackward
: return Backward(); break;
498 case tokDirection
: return Direction(); break;
499 case tokTurnLeft
: return TurnLeft(); break;
500 case tokTurnRight
: return TurnRight(); break;
501 case tokCenter
: return Center(); break;
502 case tokSetPenWidth
: return SetPenWidth(); break;
503 case tokPenUp
: return PenUp(); break;
504 case tokPenDown
: return PenDown(); break;
505 case tokSetFgColor
: return SetFgColor(); break;
506 case tokSetBgColor
: return SetBgColor(); break;
507 case tokResizeCanvas
: return ResizeCanvas(); break;
508 case tokSpriteShow
: return SpriteShow(); break;
509 case tokSpriteHide
: return SpriteHide(); break;
510 case tokSpritePress
: return SpritePress(); break;
511 case tokSpriteChange
: return SpriteChange(); break;
513 case tokPrint
: return Print(); break;
514 case tokInputWindow
: return InputWindow(); break;
515 case tokMessage
: return Message(); break;
516 case tokFontType
: return FontType(); break;
517 case tokFontSize
: return FontSize(); break;
518 case tokRepeat
: return Repeat(); break;
519 case tokRandom
: return Random(); break;
520 case tokWait
: return Wait(); break;
521 case tokWrapOn
: return WrapOn(); break;
522 case tokWrapOff
: return WrapOff(); break;
523 case tokReset
: return Reset(); break;
525 case tokEOF
: return EndOfFile(); break;
527 case tokEnd
: Error(currentToken
, i18n("Cannot understand ']'"), 1050);
529 return new TreeNode(currentToken
, Unknown
);
532 case tokBegin
: Error(currentToken
, i18n("Cannot understand '['"), 1050);
534 return new TreeNode(currentToken
, Unknown
);
539 if (currentToken
.type
!= tokEnd
)
541 Error(currentToken
, i18n("Cannot understand '%1'").arg(currentToken
.look
), 1060);
545 return new TreeNode(currentToken
, Unknown
); // fall-though for unknowns
549 TreeNode
* Parser::Block()
551 TreeNode
* block
= new TreeNode(currentToken
, blockNode
, "block");
553 while (currentToken
.type
== tokEOL
) getToken(); // skip newlines
554 matchToken(tokBegin
);
555 while (currentToken
.type
== tokEOL
) getToken(); // skip newlines
556 while ( (currentToken
.type
!= tokEnd
) && (currentToken
.type
!= tokEOF
) )
558 block
->appendChild( Statement() );
559 while (currentToken
.type
== tokEOL
) getToken(); // blocks can have newlines between their statements
570 // Functions that take NO arguments
572 TreeNode
* Parser::Clear()
574 TreeNode
* node
= new TreeNode(currentToken
, ClearNode
);
575 preservedToken
= currentToken
;
581 TreeNode
* Parser::Center()
583 TreeNode
* node
= new TreeNode(currentToken
, CenterNode
);
584 preservedToken
= currentToken
;
590 TreeNode
* Parser::PenUp()
592 TreeNode
* node
= new TreeNode(currentToken
, PenUpNode
);
593 preservedToken
= currentToken
;
599 TreeNode
* Parser::PenDown()
601 TreeNode
* node
= new TreeNode(currentToken
, PenDownNode
);
602 preservedToken
= currentToken
;
608 TreeNode
* Parser::SpriteShow()
610 TreeNode
* node
= new TreeNode(currentToken
, SpriteShowNode
);
611 preservedToken
= currentToken
;
617 TreeNode
* Parser::SpriteHide()
619 TreeNode
* node
= new TreeNode(currentToken
, SpriteHideNode
);
620 preservedToken
= currentToken
;
626 TreeNode
* Parser::SpritePress()
628 TreeNode
* node
= new TreeNode(currentToken
, SpritePressNode
);
629 preservedToken
= currentToken
;
635 TreeNode
* Parser::WrapOn()
637 TreeNode
* node
= new TreeNode(currentToken
, WrapOnNode
);
638 preservedToken
= currentToken
;
644 TreeNode
* Parser::WrapOff()
646 TreeNode
* node
= new TreeNode(currentToken
, WrapOffNode
);
647 preservedToken
= currentToken
;
653 TreeNode
* Parser::Reset()
655 TreeNode
* node
= new TreeNode(currentToken
, ResetNode
);
656 preservedToken
= currentToken
;
665 // Functions that take 1 arguments
667 TreeNode
* Parser::GoX()
669 TreeNode
* node
= new TreeNode(currentToken
, GoXNode
);
670 preservedToken
= currentToken
;
672 appendParameters(node
);
678 TreeNode
* Parser::GoY()
680 TreeNode
* node
= new TreeNode(currentToken
, GoYNode
);
681 preservedToken
= currentToken
;
683 appendParameters(node
);
689 TreeNode
* Parser::Forward()
691 TreeNode
* node
= new TreeNode(currentToken
, ForwardNode
);
692 preservedToken
= currentToken
;
694 appendParameters(node
);
700 TreeNode
* Parser::Backward()
702 TreeNode
* node
= new TreeNode(currentToken
, BackwardNode
);
703 preservedToken
= currentToken
;
705 appendParameters(node
);
710 TreeNode
* Parser::Direction()
712 TreeNode
* node
= new TreeNode(currentToken
, DirectionNode
);
713 preservedToken
= currentToken
;
715 appendParameters(node
);
720 TreeNode
* Parser::TurnLeft()
722 TreeNode
* node
= new TreeNode(currentToken
, TurnLeftNode
);
723 preservedToken
= currentToken
;
725 appendParameters(node
);
730 TreeNode
* Parser::TurnRight()
732 TreeNode
* node
= new TreeNode(currentToken
, TurnRightNode
);
733 preservedToken
= currentToken
;
735 appendParameters(node
);
740 TreeNode
* Parser::SetPenWidth()
742 TreeNode
* node
= new TreeNode(currentToken
, SetPenWidthNode
);
743 preservedToken
= currentToken
;
745 appendParameters(node
);
750 TreeNode
* Parser::Message()
752 TreeNode
* node
= new TreeNode(currentToken
, MessageNode
);
753 preservedToken
= currentToken
;
755 appendParameters(node
);
760 TreeNode
* Parser::InputWindow()
762 TreeNode
* node
= new TreeNode(currentToken
, InputWindowNode
);
763 preservedToken
= currentToken
;
765 node
->appendChild( Expression() );
766 // matchToken(tokEOL); this command can return values so can be used as expression/parameter
770 TreeNode
* Parser::SpriteChange()
772 TreeNode
* node
= new TreeNode(currentToken
, SpriteChangeNode
);
773 preservedToken
= currentToken
;
775 appendParameters(node
);
780 TreeNode
* Parser::FontType()
782 TreeNode
* node
= new TreeNode(currentToken
, FontTypeNode
);
783 preservedToken
= currentToken
;
785 appendParameters(node
);
790 TreeNode
* Parser::FontSize()
792 TreeNode
* node
= new TreeNode(currentToken
, FontSizeNode
);
793 preservedToken
= currentToken
;
795 appendParameters(node
);
800 TreeNode
* Parser::Wait()
802 TreeNode
* node
= new TreeNode(currentToken
, WaitNode
);
803 preservedToken
= currentToken
;
805 appendParameters(node
);
810 TreeNode
* Parser::ExternalRun()
812 TreeNode
* node
= new TreeNode(currentToken
, runNode
);
813 preservedToken
= currentToken
;
815 node
->appendChild( Expression() );
816 // matchToken(tokEOL); this command can return values so can be used as expression/parameter
822 // Functions that take 2 arguments
824 TreeNode
* Parser::Go()
826 TreeNode
* node
= new TreeNode(currentToken
, GoNode
);
827 preservedToken
= currentToken
;
829 appendParameters(node
);
834 TreeNode
* Parser::ResizeCanvas()
836 TreeNode
* node
= new TreeNode(currentToken
, ResizeCanvasNode
);
837 preservedToken
= currentToken
;
839 appendParameters(node
);
844 TreeNode
* Parser::Random()
846 TreeNode
* node
= new TreeNode(currentToken
, RandomNode
);
847 preservedToken
= currentToken
;
849 appendParameters(node
);
850 // matchToken(tokEOL); this command can return values so can be used as expression/parameter
857 // Functions that take 3 arguments
859 TreeNode
* Parser::SetFgColor()
861 TreeNode
* node
= new TreeNode(currentToken
, SetFgColorNode
);
862 preservedToken
= currentToken
;
864 appendParameters(node
);
869 TreeNode
* Parser::SetBgColor()
871 TreeNode
* node
= new TreeNode(currentToken
, SetBgColorNode
);
872 preservedToken
= currentToken
;
874 appendParameters(node
);
882 // Weirdo's (learn, execution controllers, print, and Other()s)
884 TreeNode
* Parser::Learn()
886 preservedToken
= currentToken
;
887 matchToken(tokLearn
); // skip the 'dummy' command
888 TreeNode
* func
= new TreeNode(currentToken
, functionNode
);
889 getToken(); // get the token after the function's name
891 TreeNode
* idList
= new TreeNode(currentToken
, idListNode
, "idlist");
892 if (currentToken
.type
!= tokBegin
)
894 if (currentToken
.type
== tokUnknown
) idList
->appendChild( getId() );
897 Error(currentToken
, "Expected a parameter name or a '[' after the learn command.", 3030);
898 getToken(); // this recovers from the error
901 while (currentToken
.type
== tokComma
)
903 matchToken(tokComma
);
904 idList
->appendChild( getId() );
907 func
->appendChild(idList
);
909 func
->appendChild( Block() ); // do the Block() thing
911 learnedFunctionList
.append( func
->getLook() );
917 TreeNode
* Parser::If()
919 TreeNode
* node
= new TreeNode(currentToken
, ifNode
);
920 preservedToken
= currentToken
;
923 node
->appendChild( Expression() );
925 if (currentToken
.type
== tokDo
) getToken(); // skip dummy word 'do'
927 if (currentToken
.type
== tokBegin
) node
->appendChild( Block() ); // if followed by a block
928 else node
->appendChild( Statement() ); // if followed by single statement
930 if (currentToken
.type
== tokElse
) // else part
934 if (currentToken
.type
== tokDo
) getToken(); // next word
936 if(currentToken
.type
== tokBegin
) node
->appendChild( Block() ); // else is followed by block
937 else node
->appendChild( Statement() );
944 TreeNode
* Parser::While()
946 TreeNode
* node
= new TreeNode(currentToken
, whileNode
);
947 preservedToken
= currentToken
;
948 matchToken(tokWhile
);
949 node
->appendChild( Expression() );
950 node
->appendChild( Block() );
955 TreeNode
* Parser::For()
957 TreeNode
* fNode
= new TreeNode(currentToken
, forNode
);
958 preservedToken
= currentToken
;
960 fNode
->appendChild( getId() ); // loop id
961 matchToken(tokAssign
);
963 fNode
->appendChild( Expression() ); // start value expression
965 fNode
->appendChild( Expression() ); // stop value expression
967 if (currentToken
.type
== tokStep
)
970 fNode
->appendChild( Expression() ); //step expression
973 while (currentToken
.type
== tokEOL
) getToken(); // newlines are allowed
974 if (currentToken
.type
== tokBegin
) fNode
->appendChild( Block() ); // for followed by a block
975 else fNode
->appendChild( Statement() ); // while followed by single statement
981 TreeNode
* Parser::Repeat()
983 TreeNode
* node
= new TreeNode(currentToken
, RepeatNode
);
984 preservedToken
= currentToken
; // preserve token, else Match() will make sure it gets lost
985 matchToken(tokRepeat
);
986 node
->appendChild( Expression() );
987 node
->appendChild( Block() );
993 TreeNode
* Parser::ForEach()
995 TreeNode
* fNode
= new TreeNode(currentToken
, forEachNode
);
996 preservedToken
= currentToken
;
997 matchToken(tokForEach
);
999 fNode
->appendChild( Expression() );
1001 fNode
->appendChild( Expression() );
1003 if (currentToken
.type
== tokBegin
) fNode
->appendChild( Block() ); // for followed by a block
1004 else fNode
->appendChild( Statement() ); // while followed by single statement
1009 TreeNode
* Parser::Print()
1011 TreeNode
* node
= new TreeNode(currentToken
, printNode
);
1012 preservedToken
= currentToken
; // preserve token, else Match() will make sure it gets lost
1014 if (currentToken
.type
== tokEOL
) return node
; // print called without expressions
1015 node
->appendChild( Expression() ); // first expression
1016 // following strings or expressions
1017 while (currentToken
.type
== tokComma
)
1019 getToken(); // the comma
1020 node
->appendChild( Expression() );
1026 TreeNode
* Parser::Return()
1028 TreeNode
* ret
= new TreeNode(currentToken
, returnNode
);
1029 matchToken(tokReturn
);
1031 ret
->appendChild( Expression() );
1036 TreeNode
* Parser::Break()
1038 TreeNode
* brk
= new TreeNode(currentToken
, breakNode
);
1039 matchToken(tokBreak
);
1044 TreeNode
* Parser::EndOfFile()
1046 TreeNode
* node
= new TreeNode(currentToken
, EndOfFileNode
);
1050 TreeNode
* Parser::Other()
1052 // this is either an assignment or a function call!
1053 kdDebug(0)<<"Parser::Other()"<<endl
;
1054 Token rememberedToken
= currentToken
; // preserve token, else Match() will make sure it gets lost
1055 matchToken(tokUnknown
);
1057 if (currentToken
.type
== tokAssign
) return Assignment(rememberedToken
);
1058 else if (learnedFunctionList
.contains(rememberedToken
.look
) > 0)
1061 node
= FunctionCall(rememberedToken
);
1062 // node->setType(funcReturnNode);
1066 Error(rememberedToken
, i18n("'%1' is neither a Logo command nor a learned command.").arg(rememberedToken
.look
), 1020);
1067 TreeNode
* errNode
= new TreeNode(rememberedToken
, Unknown
);
1069 // skip the rest of the line
1070 while (currentToken
.type
!= tokEOL
) getToken();
1076 void Parser::Error(Token
& t
, const QString
& s
, uint code
)
1078 emit
ErrorMsg(t
, s
, code
);
1082 #include "parser.moc"