/*! \brief \fn Parser::Term \param get \return const double */ const double Parser::Term (const bool get) // multiply and divide { double left = Primary (get); while (true) { switch (type_) { case MULTIPLY: left *= Primary (true); break; case DIVIDE: { double d = Primary (true); if (d == 0.0) { //throw std::runtime_error ("Divide by zero"); } left /= d; break; } case BINAND: qWarning()<<"BINAND"; left = ((ulong)left) & ((ulong) Primary(true)); break; case BINOR: qWarning()<<"BINOR"; left = ((ulong)left) | ((ulong) Primary(true)); break; default: return left; } // end of switch on type } // end of loop } // end of Parser::Term
/* <Factor> ::= - <Primary> | <Primary> */ void SyntaxAnalyzer::Factor() { if(rrr == o_minus) { NextRecord(); Primary(); logger.Log("<Factor> ::= - <Primary>"); } else { Primary(); logger.Log("<Factor> ::= <Primary>"); } }
const double Parser::Term (const bool get) // multiply and divide { double left = Primary (get); while (true) { switch (type_) { case MULTIPLY: left *= Primary (true); break; case DIVIDE: { double d = Primary (true); if (d == 0.0) throw std::runtime_error ("Divisione per 0"); left /= d; break; } default: return left; } // end of switch on type } // end of loop } // end of Parser::Term
// Purpose: Tests the production rule for Factor bool syntaxparser::Factor(){ bool Factor = false; if(lexeme == "-"){ print(); cout<<endl; Lexer(); if(displayFlag){ cout<<"<Factor> ::= -<Primary>"<<endl; printproduction("<Factor> ::= -<Primary>"); } Primary(); Factor = true; }else { if(displayFlag){ cout<<"<Factor> ::= <Primary>"<<endl; printproduction("<Factor> ::= <Primary>"); } Primary(); Factor = true; } return Factor; }
static AIExpType_t *ReadConditionExpression( pc_token_list **list, AIOpType_t op2 ) { AIExpType_t *t; AIOpType_t op; if ( !*list ) { Log::Warn( "Unexpected end of file" ); return nullptr; } t = Primary( list ); if ( !t ) { return nullptr; } op = opTypeFromToken( &(*list)->token ); while ( isBinaryOp( op ) && opCompare( op, op2 ) >= 0 ) { AIExpType_t *t1; pc_token_list *prev = *list; AIOp_t *exp = newOp( *list ); *list = (*list)->next; t1 = ReadConditionExpression( list, op ); if ( !t1 ) { Log::Warn( "Missing right operand for %s on line %d", opTypeToString( op ), prev->token.line ); FreeExpression( t ); FreeOp( exp ); return nullptr; } t = makeExpression( exp, t, t1 ); op = opTypeFromToken( &(*list)->token ); } return t; }
//evaluates and * and / expression void CStateParser::Term(CTokenizer &tok,CStateManager &StateManager) { Primary(tok,StateManager); //search for operators while( tok.CheckToken("*",false) || tok.CheckToken("/",false) || tok.CheckToken("=",false) || tok.CheckToken("!=",false) || tok.CheckToken("<",false) || tok.CheckToken("<=",false) || tok.CheckToken(">",false) || tok.CheckToken(">=",false) || tok.CheckToken(":",false) || /*tok.CheckToken("&&",false) || tok.CheckToken("||",false)||*/ tok.CheckToken("^^",false) || tok.CheckToken("&",false) || tok.CheckToken("~",false) || tok.CheckToken("|",false) || tok.CheckToken("^",false) || tok.CheckToken("%",false) || tok.CheckToken("(", false) && !tok.AtEndOfLine() ) { if( tok.CheckToken("*") ) { //Have we a ** operator? if( tok.CheckToken("*") ) { Primary(tok,StateManager); StateManager.AddInstruction(OP_SQUARE,0,"#"); }else { Primary(tok,StateManager); StateManager.AddInstruction(OP_MUL,0,"#"); } } if( tok.CheckToken("/") ) { Primary(tok,StateManager); StateManager.AddInstruction(OP_DIV,0,"#"); } if( tok.CheckToken("=") ) { //check for intervall operator if( tok.CheckToken("(") ) { //evaluate first expression EvaluateExpression(tok,StateManager); if( !tok.CheckToken(",") ) Error("Expectetd a , in intervall operator",tok); //evaluate second expression EvaluateExpression(tok,StateManager); //intervall op =(,) if( tok.CheckToken(")") ) { StateManager.AddInstruction(OP_INTERVALOP4,0,"#"); }else if( tok.CheckToken("]") ) { StateManager.AddInstruction(OP_INTERVALOP3,0,"#"); } }else if (tok.CheckToken("[") ) { //evaluate first expression EvaluateExpression(tok,StateManager); if( !tok.CheckToken(",") ) Error("Expectetd a , in intervall operator",tok); //evaluate second expression EvaluateExpression(tok,StateManager); //intervall op =[,) if( tok.CheckToken(")") ) { StateManager.AddInstruction(OP_INTERVALOP2,0,"#"); }else if( tok.CheckToken("]") ) { StateManager.AddInstruction(OP_INTERVALOP1,0,"#"); } } else // is the = op { //evalute the right side of the operator Primary(tok,StateManager); StateManager.AddInstruction(OP_EQUAL,0,"#"); } } if( tok.CheckToken(":") ) { //evalute the right side of the operator if(tok.CheckToken("=")) { EvaluateExpression(tok,StateManager); PrintMessage("TODO:Handel assign operator :="); } } if( tok.CheckToken("!=") ) { //evalute the right side of the operator //check for intervall operator if( tok.CheckToken("(") ) { //evaluate first expression EvaluateExpression(tok,StateManager); if( !tok.CheckToken(",") ) Error("Expectetd a , in intervall operator",tok); //evaluate second expression EvaluateExpression(tok,StateManager); //intervall op !=(,) if( tok.CheckToken(")") ) { StateManager.AddInstruction(OP_INTERVALOP8,0,"#"); }else if( tok.CheckToken("]") ) { StateManager.AddInstruction(OP_INTERVALOP7,0,"#"); } }else if (tok.CheckToken("[") ) { //evaluate first expression EvaluateExpression(tok,StateManager); if( !tok.CheckToken(",") ) Error("Expectetd a , in intervall operator",tok); //evaluate second expression EvaluateExpression(tok,StateManager); //intervall op !=[,) if( tok.CheckToken(")") ) { StateManager.AddInstruction(OP_INTERVALOP6,0,"#"); }else if( tok.CheckToken("]") ) { StateManager.AddInstruction(OP_INTERVALOP5,0,"#"); } } else // is the != op { //evalute the right side of the operator //EvaluateExpression(tok,StateManager); Primary(tok,StateManager); StateManager.AddInstruction(OP_NOTEQUAL,0,"#"); continue; } //EvaluateExpression(tok,StateManager); //StateManager.AddInstruction(OP_NOTEQUAL,0,"#"); } if( tok.CheckToken("<") ) { //evalute the right side of the operator EvaluateExpression(tok,StateManager); StateManager.AddInstruction(OP_LESS,0,"#"); } if( tok.CheckToken("<=") ) { //evalute the right side of the operator EvaluateExpression(tok,StateManager); StateManager.AddInstruction(OP_LESSEQUAL,0,"#"); } if( tok.CheckToken(">") ) { //evalute the right side of the operator EvaluateExpression(tok,StateManager); StateManager.AddInstruction(OP_GREATER,0,"#"); } if( tok.CheckToken(">=") ) { //evalute the right side of the operator EvaluateExpression(tok,StateManager); StateManager.AddInstruction(OP_GRAETEREQUAL,0,"#"); } // if( tok.CheckToken("&&") ) // { //evalute the right side of the operator // EvaluateExpression(tok,StateManager); // StateManager.AddInstruction(OP_LOGAND,0,"#"); // } // if( tok.CheckToken("||") ) // { //evalute the right side of the operator // EvaluateExpression(tok,StateManager); // StateManager.AddInstruction(OP_LOGOR,0,"#"); // } if( tok.CheckToken("^^") ) // is this realy needed? //FIXME:Cant read ^^ { //evalute the right side of the operator EvaluateExpression(tok,StateManager); StateManager.AddInstruction(OP_LOGXOR,0,"#"); } if( tok.CheckToken("&") ) { //evalute the right side of the operator Primary(tok,StateManager); StateManager.AddInstruction(OP_AND,0,"#"); } if( tok.CheckToken("~") ) { //evalute the right side of the operator Primary(tok,StateManager); StateManager.AddInstruction(OP_NOT,0,"#"); } if( tok.CheckToken("|") ) { //evalute the right side of the operator Primary(tok,StateManager); StateManager.AddInstruction(OP_OR,0,"#"); } if( tok.CheckToken("^") ) { //evalute the right side of the operator Primary(tok,StateManager); StateManager.AddInstruction(OP_XOR,0,"#"); } if( tok.CheckToken("%") ) { //evalute the right side of the operator Primary(tok,StateManager); StateManager.AddInstruction(OP_MOD,0,"#"); } if (tok.CheckToken("(")) { EvaluateExpression(tok,StateManager); if( !tok.CheckToken(")") ) Error("Missing )",tok); } } }
//evaluates a primary void CStateParser::Primary(CTokenizer &tok,CStateManager &StateManager) { //a negate operator if( tok.CheckToken("-") ) { //EvaluateExpression(tok,StateManager); Primary(tok,StateManager); StateManager.AddInstruction(OP_NEG,0,"#"); }else if( tok.CheckTokenIsNumber() ) //we have a number { StateManager.AddInstruction(OP_PUSH,tok.GetFloat(),"#"); }else if( tok.CheckTokenIsQuotedString() ) //it is a "quitedstring" { StateManager.AddInstruction(OP_PUSH,0,tok.GetToken()); }else if( tok.CheckToken("(") ) //here we have to check a lot of possibilitys { EvaluateExpression(tok,StateManager); if( !tok.CheckToken(")") ) Error("Missing )",tok); }else if( tok.CheckToken("!") ) { Primary(tok,StateManager); StateManager.AddInstruction(OP_NOT,0,"#"); } else //check for a trigger name { std::string ret = tok.GetToken(); int i=GetTriggerType(ret.c_str(),tok); if ( i == OP_Vel - OP_Abs) { if (tok.CheckToken("x")) { StateManager.AddInstruction(OP_Vel,1.0,"#"); } else if (tok.CheckToken("y")) { StateManager.AddInstruction(OP_Vel,0.0,"#"); } }else if ( i == OP_Pos - OP_Abs) { if (tok.CheckToken("x")) { StateManager.AddInstruction(OP_Pos,1.0,"#"); } else if (tok.CheckToken("y")) { StateManager.AddInstruction(OP_Pos,0.0,"#"); } } else if ( i == OP_Const - OP_Abs) { if (!tok.CheckToken("(")) Error("Missing (",tok); StateManager.AddInstruction(OP_Const,0.0,tok.GetToken()); if (!tok.CheckToken(")")) Error("Missing )",tok); } else if ( i == OP_IfElse - OP_Abs) { if (!tok.CheckToken("(")) Error("Missing (",tok); EvaluateExpression(tok,StateManager); if (!tok.CheckToken(",")) Error("Missing ,",tok); Term(tok,StateManager); if (!tok.CheckToken(",")) Error("Missing ,",tok); Term(tok,StateManager); StateManager.AddInstruction(OP_IfElse,0,"#"); if (!tok.CheckToken(")")) Error("Missing )",tok); } else if (i == OP_StateType - OP_Abs) { if (tok.CheckToken("=")) { StateManager.AddInstruction(OP_StateType,0,"#"); StateManager.AddInstruction(OP_PUSH,0,tok.GetToken()); StateManager.AddInstruction(OP_EQUAL,0,"#"); }else if (tok.CheckToken("!=")) { StateManager.AddInstruction(OP_StateType,0,"#"); StateManager.AddInstruction(OP_PUSH,0,tok.GetToken()); StateManager.AddInstruction(OP_NOTEQUAL,0,"#"); } } else if (i == OP_P2StateType - OP_Abs) { if (tok.CheckToken("=")) { StateManager.AddInstruction(OP_P2StateType,0,"#"); StateManager.AddInstruction(OP_PUSH,0,tok.GetToken()); StateManager.AddInstruction(OP_EQUAL,0,"#"); }else if (tok.CheckToken("!=")) { StateManager.AddInstruction(OP_P2StateType,0,"#"); StateManager.AddInstruction(OP_PUSH,0,tok.GetToken()); StateManager.AddInstruction(OP_NOTEQUAL,0,"#"); } } else if (i == OP_P2MoveType - OP_Abs) { if (tok.CheckToken("=")) { StateManager.AddInstruction(OP_P2MoveType,0,"#"); StateManager.AddInstruction(OP_PUSH,0,tok.GetToken()); StateManager.AddInstruction(OP_EQUAL,0,"#"); }else if (tok.CheckToken("!=")) { StateManager.AddInstruction(OP_P2MoveType,0,"#"); StateManager.AddInstruction(OP_PUSH,0,tok.GetToken()); StateManager.AddInstruction(OP_NOTEQUAL,0,"#"); } } else if (i == OP_GetHitVar - OP_Abs) { if (!tok.CheckToken("(")) Error("Missing (",tok); StateManager.AddInstruction(OP_GetHitVar,0,tok.GetToken()); if (!tok.CheckToken(")")) Error("Missing )",tok); } else if (i == OP_HitDefAttr - OP_Abs) { while (!tok.AtEndOfLine()) tok.GetToken(); } else if (i == OP_P2BodyDist - OP_Abs) { while (!tok.AtEndOfLine()) tok.GetToken(); } else { StateManager.AddInstruction(i+OP_Abs,0,"#"); } } }
/*! \brief \fn Parser::Primary \param get \return const double */ const double Parser::Primary (const bool get) // primary (base) tokens { if (get) GetToken (); // one-token lookahead switch (type_) { case NUMBER: { double v = value_; GetToken (true); // get next one (one-token lookahead) return v; } case NAME: { std::string word = word_; GetToken (true); if (type_ == LHPAREN) { // might be single-argument function (eg. abs (x) ) std::map<std::string, OneArgFunction>::const_iterator si; si = OneArgumentFunctions.find (word); if (si != OneArgumentFunctions.end ()) { double v = Expression (true); // get argument CheckToken (RHPAREN); GetToken (true); // get next one (one-token lookahead) return si->second (v); // evaluate function } // might be double-argument function (eg. roll (6, 2) ) std::map<std::string, TwoArgFunction>::const_iterator di; di = TwoArgumentFunctions.find (word); if (di != TwoArgumentFunctions.end ()) { double v1 = Expression (true); // get argument 1 (not commalist) CheckToken (COMMA); double v2 = Expression (true); // get argument 2 (not commalist) CheckToken (RHPAREN); GetToken (true); // get next one (one-token lookahead) return di->second (v1, v2); // evaluate function } // might be double-argument function (eg. roll (6, 2) ) std::map<std::string, ThreeArgFunction>::const_iterator ti; ti = ThreeArgumentFunctions.find (word); if (ti != ThreeArgumentFunctions.end ()) { double v1 = Expression (true); // get argument 1 (not commalist) CheckToken (COMMA); double v2 = Expression (true); // get argument 2 (not commalist) CheckToken (COMMA); double v3 = Expression (true); // get argument 3 (not commalist) CheckToken (RHPAREN); GetToken (true); // get next one (one-token lookahead) return ti->second (v1, v2, v3); // evaluate function } //throw std::runtime_error ("Function '" + word + "' not implemented."); } // not a function? must be a symbol in the symbol table double & v = symbols_ [word]; // get REFERENCE to symbol table entry // change table entry with expression? (eg. a = 22, or a = 22) switch (type_) { // maybe check for NaN or Inf here (see: isinf, isnan functions) case ASSIGN: v = Expression (true); break; case ASSIGN_ADD: v += Expression (true); break; case ASSIGN_SUB: v -= Expression (true); break; case ASSIGN_MUL: v *= Expression (true); break; case ASSIGN_DIV: { double d = Expression (true); if (d == 0.0) { //throw std::runtime_error ("Divide by zero"); } v /= d; break; // change table entry with expression } // end of ASSIGN_DIV default: break; // do nothing for others } // end of switch on type_ return v; // and return new value } case MINUS: // unary minus return - Primary (true); case NOT: // unary not return (Primary (true) == 0.0) ? 1.0 : 0.0;; case LHPAREN: { double v = CommaList (true); // inside parens, you could have commas CheckToken (RHPAREN); GetToken (true); // eat the ) return v; } default: break; //throw std::runtime_error ("Unexpected token: " + word_); } // end of switch on type } // end of Parser::Primary