TreeNode* Parser::ForEach() { TreeNode* fNode = new TreeNode(currentToken, forEachNode); preservedToken = currentToken; matchToken(tokForEach); fNode->appendChild( Expression() ); matchToken(tokIn); fNode->appendChild( Expression() ); if (currentToken.type == tokBegin) fNode->appendChild( Block() ); // for followed by a block else fNode->appendChild( Statement() ); // while followed by single statement return fNode; }
TreeNode* Parser::Block() { TreeNode* block = new TreeNode(currentToken, blockNode, "block"); while (currentToken.type == tokEOL) getToken(); // skip newlines matchToken(tokBegin); while (currentToken.type == tokEOL) getToken(); // skip newlines while ( (currentToken.type != tokEnd) && (currentToken.type != tokEOF) ) { block->appendChild( Statement() ); while (currentToken.type == tokEOL) getToken(); // blocks can have newlines between their statements } matchToken(tokEnd); return block; }
TreeNode* Parser::FunctionCall(Token maybeFunctionCall) { kdDebug(0)<<"Parser::FunctionCall() [using identifier: '"<<maybeFunctionCall.look<<"']"<<endl; TreeNode* fcall = new TreeNode(maybeFunctionCall, functionCallNode); TreeNode* paramList = new TreeNode(currentToken, idListNode, "idlist"); // if (currentToken.type != tokEOL && currentToken.type != tokEOF) if (currentToken.type == tokNumber || currentToken.type == tokString || currentToken.type == tokUnknown) // only if there is a possible parameter given after the call... { TreeNode* expr = Expression(); if (expr->getType() == Unknown) Error(currentToken, i18n("Expected an expression"), 1020); else paramList->appendChild(expr); while (currentToken.type == tokComma) { matchToken(tokComma); expr = Expression(); if (expr->getType() == Unknown) Error(currentToken, i18n("Expected an expression"), 1020); else paramList->appendChild(expr); } } fcall->appendChild(paramList); return fcall; }
TreeNode* Parser::getId() { TreeNode* n = new TreeNode(currentToken, idNode); n->setLook(currentToken.look); matchToken(tokUnknown); // Id's are ofcouse not yet known return n; }
TreeNode* Parser::Break() { TreeNode* brk = new TreeNode(currentToken, breakNode); matchToken(tokBreak); return brk; }
static void findPerl6Tags (void) { struct p6Ctx ctx; #define RESET_TOKENS() do { ctx.n_tokens = 0; } while (0) #define PUSH_TOKEN(_t_) do { \ if (ctx.n_tokens < ARRAY_SIZE(ctx.tokens)) { \ ctx.tokens[ ctx.n_tokens ] = _t_; \ ++ctx.n_tokens; \ } else { \ Assert(!"Token stack overflown: this is quite odd"); \ RESET_TOKENS(); \ } \ } while (0) initP6Ctx(&ctx); const char *s; int len; while ((len = getNonSpaceStr(&ctx, &s)) > 0) { enum token token = matchToken(s, len); if ((int) token >= 0) { PUSH_TOKEN(token); } else if (ctx.n_tokens > 0) { possiblyMakeTag(&ctx, s, len); RESET_TOKENS(); } } deinitP6Ctx(&ctx); }
TreeNode* Parser::SpritePress() { TreeNode* node = new TreeNode(currentToken, SpritePressNode); preservedToken = currentToken; getToken(); matchToken(tokEOL); return node; }
TreeNode* Parser::Reset() { TreeNode* node = new TreeNode(currentToken, ResetNode); preservedToken = currentToken; getToken(); matchToken(tokEOL); return node; }
TreeNode* Parser::WrapOff() { TreeNode* node = new TreeNode(currentToken, WrapOffNode); preservedToken = currentToken; getToken(); matchToken(tokEOL); return node; }
TreeNode* Parser::Term() { TreeNode* termNode = signedFactor(); TreeNode* pos = termNode; TreeNode* left = NULL; TreeNode* right = NULL; while ( (currentToken.type == tokMul) || (currentToken.type == tokDev) || (currentToken.type == tokAnd) ) { // while is is a multiplicative operator do... left = pos; pos = new TreeNode(currentToken, Unknown); pos->appendChild(left); switch (currentToken.type) { case tokMul: matchToken(tokMul); right = signedFactor(); pos->setType(mulNode); break; case tokDev: matchToken(tokDev); right = signedFactor(); pos->setType(divNode); break; case tokAnd: matchToken(tokAnd); right = signedFactor(); pos->setType(andNode); break; default: Error(currentToken, i18n("Expected '*' or '/'"), 1030); getToken(); return pos; break; } if (right != NULL) pos->appendChild(right); termNode = pos; } return termNode; }
TreeNode* Parser::TurnRight() { TreeNode* node = new TreeNode(currentToken, TurnRightNode); preservedToken = currentToken; getToken(); appendParameters(node); matchToken(tokEOL); return node; }
TreeNode* Parser::SpriteChange() { TreeNode* node = new TreeNode(currentToken, SpriteChangeNode); preservedToken = currentToken; getToken(); appendParameters(node); matchToken(tokEOL); return node; }
TreeNode* Parser::Backward() { TreeNode* node = new TreeNode(currentToken, BackwardNode); preservedToken = currentToken; getToken(); appendParameters(node); matchToken(tokEOL); return node; }
TreeNode* Parser::Direction() { TreeNode* node = new TreeNode(currentToken, DirectionNode); preservedToken = currentToken; getToken(); appendParameters(node); matchToken(tokEOL); return node; }
TreeNode* Parser::ResizeCanvas() { TreeNode* node = new TreeNode(currentToken, ResizeCanvasNode); preservedToken = currentToken; getToken(); appendParameters(node); matchToken(tokEOL); return node; }
TreeNode* Parser::Return() { TreeNode* ret = new TreeNode(currentToken, returnNode); matchToken(tokReturn); ret->appendChild( Expression() ); return ret; }
TreeNode* Parser::Repeat() { TreeNode* node = new TreeNode(currentToken, RepeatNode); preservedToken = currentToken; // preserve token, else Match() will make sure it gets lost matchToken(tokRepeat); node->appendChild( Expression() ); node->appendChild( Block() ); return node; }
TreeNode* Parser::SetBgColor() { TreeNode* node = new TreeNode(currentToken, SetBgColorNode); preservedToken = currentToken; getToken(); appendParameters(node); matchToken(tokEOL); return node; }
TreeNode* Parser::While() { TreeNode* node = new TreeNode(currentToken, whileNode); preservedToken = currentToken; matchToken(tokWhile); node->appendChild( Expression() ); node->appendChild( Block() ); return node; }
TreeNode* Parser::FontSize() { TreeNode* node = new TreeNode(currentToken, FontSizeNode); preservedToken = currentToken; getToken(); appendParameters(node); matchToken(tokEOL); return node; }
void Parser::appendParameters(TreeNode* node) { node->appendChild( Expression() ); // append the first papameter while (currentToken.type == tokComma) { matchToken(tokComma); // push through the comma if (currentToken.type == tokEOL) return; // catch forgotten expressions, like "go 10, " node->appendChild( Expression() ); } }
void startSyntaxTree() { int temp = 0; openLexFile(); getNextToken(); while(!matchToken(PROGRAM)) { getNextToken(); } temp = lookupNumber(PROGRAM); addTokens(hand.root, getTokenName(temp), getTokenType(temp)); }
TreeNode* Parser::For() { TreeNode* fNode = new TreeNode(currentToken, forNode); preservedToken = currentToken; matchToken(tokFor); fNode->appendChild( getId() ); // loop id matchToken(tokAssign); fNode->appendChild( Expression() ); // start value expression matchToken(tokTo); fNode->appendChild( Expression() ); // stop value expression if (currentToken.type == tokStep) { matchToken(tokStep); fNode->appendChild( Expression() ); //step expression } while (currentToken.type == tokEOL) getToken(); // newlines are allowed if (currentToken.type == tokBegin) fNode->appendChild( Block() ); // for followed by a block else fNode->appendChild( Statement() ); // while followed by single statement return fNode; }
TreeNode* Parser::Print() { TreeNode* node = new TreeNode(currentToken, printNode); preservedToken = currentToken; // preserve token, else Match() will make sure it gets lost getToken(); if (currentToken.type == tokEOL) return node; // print called without expressions node->appendChild( Expression() ); // first expression // following strings or expressions while (currentToken.type == tokComma) { getToken(); // the comma node->appendChild( Expression() ); } matchToken(tokEOL); return node; }
TreeNode* Parser::Assignment(Token t) { TreeNode* node = new TreeNode(t, assignNode); matchToken(tokAssign); // match the '=' // the child is the expression or RHV of assignment TreeNode* expr = NULL; // if (currentToken.type == tokUnknown) expr = Other(); // in case of an functioncall // else expr = Expression(); -------> fuctioncalls get caught in Expression() and co. expr = Expression(); node->appendChild(expr); return node; }
DFA& DFA::run(string& fIn, string& fOut) { char input; bool runnable = true; bool inputable = true; tokenCnt = 0; currentState = startState; string buffer = ""; int inputCnt = 0; while(runnable) { if (inputable && inputCnt >= fIn.size() ) { break; } if ( inputable ) { input = fIn[ inputCnt++ ]; } inputable = true; t_DFA_Trans next = trans[currentState][input]; stringstream buf; if ( next.valid == _ERROR_ ) { runnable = false; buf<<"ERROR Character ["<<input+","<<(int)input<<"]"<<endl; } else if ( next.valid == NORMAL || next.valid == PREDICATE) { if ( next.valid == NORMAL ) { if ( !next.ignore )buffer += input; } else if ( next.valid == PREDICATE ) { inputable = false; } if ( hasFinish(next.state) ) { matchToken(buf, buffer, finish.find(next.state)->second); buffer = ""; currentState = startState; } else { currentState = next.state; } } fOut += buf.str(); } return *this; }
TreeNode* Parser::Other() { // this is either an assignment or a function call! kdDebug(0)<<"Parser::Other()"<<endl; Token rememberedToken = currentToken; // preserve token, else Match() will make sure it gets lost matchToken(tokUnknown); if (currentToken.type == tokAssign) return Assignment(rememberedToken); else if (learnedFunctionList.contains(rememberedToken.look) > 0) { TreeNode* node; node = FunctionCall(rememberedToken); // node->setType(funcReturnNode); return node; } Error(rememberedToken, i18n("'%1' is neither a Logo command nor a learned command.").arg(rememberedToken.look), 1020); TreeNode* errNode = new TreeNode(rememberedToken, Unknown); // skip the rest of the line while (currentToken.type != tokEOL) getToken(); return errNode; }
TreeNode* Parser::Factor() { TreeNode* node; Token rememberedToken = currentToken; switch (currentToken.type) { case tokBraceOpen: matchToken(tokBraceOpen); node = Expression(); matchToken(tokBraceClose); break; case tokUnknown: node = getId(); if (learnedFunctionList.contains(rememberedToken.look) > 0) // is function call { delete node; node = FunctionCall(rememberedToken); node->setType(funcReturnNode); // expect returned value on stack } break; case tokString: node = new TreeNode(currentToken, constantNode); { // extra scope to localize the QString 'str' QString str = currentToken.look; if ( currentToken.look.endsWith("\"") ) { // cut off the quotes and store the value str.remove(0, 1).truncate( currentToken.look.length() - 2 ); } else // problems but we need to keep it moving { str.remove(0, 1); // cut off the first quote only Error(currentToken, i18n("String text not properly delimited with a ' \" ' (double quote)"), 1060); } node->setValue(str); } matchToken(tokString); break; case tokNumber: node = new TreeNode(currentToken, constantNode); node->setValue(currentToken.value); matchToken(tokNumber); break; case tokRun: node = ExternalRun(); break; case tokInputWindow: node = InputWindow(); break; case tokRandom: node = Random(); break; case tokEOL: node = new TreeNode(currentToken, Unknown); break; default: QString s = currentToken.look; if ( s.isEmpty() || currentToken.type == tokEOF ) { Error(currentToken, i18n("INTERNAL ERROR NR %1: please sent this Logo script to KTurtle developers").arg(1), 1020); // if this error occurs the see the Parser::Repeat for the good solution using 'preservedToken' } else { Error(currentToken, i18n("Cannot understand '%1', expected an expression after the '%2' command").arg(s).arg(preservedToken.look), 1020); } node = new TreeNode(currentToken, Unknown); getToken(); break; } return node; }
/* Parse and Translate an Expression */ TreeNode* Parser::Expression() { TreeNode* retExp = Term(); // preset the base-TreeNode as it eventually will be returned TreeNode* pos = retExp; TreeNode* left = NULL; TreeNode* right = NULL; while ( isAddOp(currentToken) ) { left = pos; pos = new TreeNode(currentToken, Unknown); pos->appendChild(left); switch (currentToken.type) { case tokPlus: matchToken(tokPlus); right = Term(); pos->setType(addNode); break; case tokMinus: matchToken(tokMinus); right = Term(); pos->setType(subNode); break; case tokGt: matchToken(tokGt); right = Term(); pos->setType(nodeGT); break; case tokLt: matchToken(tokLt); right = Term(); pos->setType(nodeLT); break; case tokGe: matchToken(tokGe); right = Term(); pos->setType(nodeGE); break; case tokLe: matchToken(tokLe); right = Term(); pos->setType(nodeLE); break; case tokEq: matchToken(tokEq); right = Term(); pos->setType(nodeEQ); break; case tokNe: matchToken(tokNe); right = Term(); pos->setType(nodeNE); break; case tokOr: matchToken(tokOr); right = Term(); pos->setType(orNode); break; default: Error(currentToken, i18n("Expected '*' or '/'"), 1040); getToken(); return pos; break; } if (right != NULL) pos->appendChild(right); retExp = pos; } return retExp; }
/* Tokens: ARCH Build architecture (x86_64) CC Compiler (cc) DEBUG Debug compilation options (-g, -Zi -Od) INC Include directory out/inc LIB Library directory (out/lib, xcode/VS: out/bin) LIBS Libraries required to link with ESP OBJ Name of compiled source (out/lib/view-MD5.o) OUT Output module (view_MD5.dylib) SHLIB Host Shared library (.lib, .so) SHOBJ Host Shared Object (.dll, .so) SRC Source code for view or controller (already templated) TMP Temp directory VS Visual Studio directory WINSDK Windows SDK directory */ char *espExpandCommand(cchar *command, cchar *source, cchar *module) { MprBuf *buf; MaAppweb *appweb; cchar *cp, *out; char *tmp; #if BLD_WIN_LIKE cchar *path; path = 0; #endif if (command == 0) { return 0; } out = mprTrimPathExt(module); buf = mprCreateBuf(-1, -1); appweb = MPR->appwebService; for (cp = command; *cp; ) { if (*cp == '$') { if (matchToken(&cp, "${ARCH}")) { /* Build architecture */ mprPutStringToBuf(buf, appweb->hostArch); #if BLD_WIN_LIKE } else if (matchToken(&cp, "${WINSDK}")) { path = mprReadRegistry("HKLM\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows", "CurrentInstallFolder"); path = strim(path, "\\", MPR_TRIM_END); mprPutStringToBuf(buf, path); } else if (matchToken(&cp, "${VS}")) { path = mprGetPathParent(mprGetPathParent(getenv("VS100COMNTOOLS"))); mprPutStringToBuf(buf, mprGetPortablePath(path)); #endif } else if (matchToken(&cp, "${CC}")) { /* Compiler */ #if BLD_WIN_LIKE // MOB - what about cross compilation path = mprJoinPath(mprGetPathParent(mprGetPathParent(getenv("VS100COMNTOOLS"))), "VC/bin/cl.exe"); mprPutStringToBuf(buf, mprGetPortablePath(path)); #else mprPutStringToBuf(buf, BLD_CC); #endif } else if (matchToken(&cp, "${DEBUG}")) { mprPutStringToBuf(buf, ESP_DEBUG); } else if (matchToken(&cp, "${INC}")) { /* Include directory (out/inc) */ mprPutStringToBuf(buf, mprResolvePath(mprGetAppDir(), "inc")); } else if (matchToken(&cp, "${LIB}")) { /* Library directory. IDE's use bin dir */ mprPutStringToBuf(buf, getOutDir(BLD_LIB_NAME)); } else if (matchToken(&cp, "${LIBS}")) { /* Required libraries to link. These may have nested ${TOKENS} */ mprPutStringToBuf(buf, espExpandCommand(ESP_LIBS, source, module)); } else if (matchToken(&cp, "${OBJ}")) { /* Output object with extension (.o) */ mprPutStringToBuf(buf, mprJoinPathExt(out, BLD_OBJ)); } else if (matchToken(&cp, "${OUT}")) { /* Output modules */ mprPutStringToBuf(buf, out); } else if (matchToken(&cp, "${SHLIB}")) { /* .lib */ mprPutStringToBuf(buf, appweb->hostOs); } else if (matchToken(&cp, "${SHOBJ}")) { /* .dll */ #ifdef BLD_HOST_SHOBJ // MOB - need this for bit mprPutStringToBuf(buf, BLD_HOST_SHOBJ); #else mprPutStringToBuf(buf, BLD_SHOBJ); #endif } else if (matchToken(&cp, "${SRC}")) { /* View (already parsed into C code) or controller source */ mprPutStringToBuf(buf, source); } else if (matchToken(&cp, "${TMP}")) { #if BLD_WIN_LIKE if ((tmp = getenv("TMP")) == 0) { tmp = getenv("TEMP"); } #else tmp = getenv("TMPDIR"); #endif mprPutStringToBuf(buf, tmp ? tmp : "."); #ifdef WIND_BASE } else if (matchToken(&cp, "${WIND_BASE}")) { mprPutStringToBuf(buf, WIND_BASE); #endif #ifdef WIND_HOME } else if (matchToken(&cp, "${WIND_HOME}")) { mprPutStringToBuf(buf, WIND_HOME); #endif #ifdef WIND_HOST_TYPE } else if (matchToken(&cp, "${WIND_HOST_TYPE}")) { mprPutStringToBuf(buf, WIND_HOST_TYPE); #endif #ifdef WIND_PLATFORM } else if (matchToken(&cp, "${WIND_PLATFORM}")) { mprPutStringToBuf(buf, WIND_PLATFORM); #endif #ifdef WIND_GNU_PATH } else if (matchToken(&cp, "${WIND_GNU_PATH}")) { mprPutStringToBuf(buf, WIND_GNU_PATH); #endif } else { mprPutCharToBuf(buf, *cp++); } } else { mprPutCharToBuf(buf, *cp++); } } mprAddNullToBuf(buf); return sclone(mprGetBufStart(buf)); }