void in2pre (char *inexp) { char t; char preExp[25]; char *rInExp; char *rPreExp; int i,j; struct Stack* stack; i=j=0; printf("\nInput Infix Expression is : %s",inexp); rInExp = strrev(inexp); printf("\nReversed input Infix Expression is : %s",rInExp); stack = createStack(25); while(rInExp[i] != '\0') { if(isParenthesis(rInExp[i]) == 1) { //Left Parenthesis printf("\nLeft Parenthesis Encountered."); while(peek(stack) != ')') { // pop until a Right parenthesis encounters if(peek(stack) != CHAR_MIN){ preExp[j] = pop(stack); j++; } } pop(stack); //Remove Left Parenthesis } else if(isParenthesis(rInExp[i]) == 2 || isOperator(rInExp[i]) == 1) { //Operator or Right Parenthesis if(isParenthesis(rInExp[i]) == 2 ) { printf("\nRight Parenthesis Encountered."); push(stack, rInExp[i]); // Push Right Parenthesis on Stack } if (isOperator(rInExp[i]) == 1) { printf("\nOperator Encountered."); while((getPrecedence(rInExp[i]) < getPrecedence(peek(stack))) && (peek(stack) != CHAR_MIN) && (isParenthesis(peek(stack)) != 2 ) ) { preExp[j] = pop(stack); j++; } push(stack, rInExp[i]); } } else{ //if t is operand preExp[j] = rInExp[i]; printf("\nOperand : %c",preExp[j]); j++; } i++; } while(peek(stack) != CHAR_MIN) { preExp[j] = pop(stack); j++; } preExp[j] = '\0'; printf("\nPreFix : %s\n",preExp); rPreExp = strrev(preExp); printf("\nFinal PreFix : %s\n",rPreExp); //printf("%c popped from stack\n", pop(stack)); //printf("%c popped from stack\n", pop(stack)); //printf("%c popped from stack\n", pop(stack)); //printf("%c popped from stack\n", pop(stack)); }
//put crtOp on stack respecting operator precedence; i.e. * can be pushed on top of + or - but not the other way round void putOperatorOnStack(char* crtOp, FILE* out) { char name[20]; char* topOp = topElement(&opStack); if (DEBUG) {printf("putOperatorOnStack(%s): crtOp = %s topOp = %s\n", D(crtOp), D(crtOp), D(topOp));} //BASE CASE: left paranthesis; push and resume if (!isOperator(topOp)) { if (DEBUG) {printf("putOperatorOnStack(%s): OP_PUSH(%s)\n", D(crtOp), D(crtOp));} push(createVElement(crtOp), &opStack, -1); return; } int opPerformed = 0; while (isOperator(topOp)) { //If the precedence of the operator which needs to be put on the stack crtOp is lower than the precedence of the operator //on the top of the stack, topOp, perform the operation denoted by topOp and the top two numbers from the RESULT_STACK. //An optimization step is performed by using the ACC, thus avoiding the need to create extra temporary variables. if (getPrecedence(crtOp) <= getPrecedence(topOp)) { if (!opPerformed) { //in the very first iteration load number from RESULT_STACK into ACC VElement* temp = pop(&resStack); if (DEBUG) {printf("putOperatorOnStack(): RES_POP(%s)\n", D(temp->data));} fprintf(out, "\tLOAD\t%s\n", temp->data); } if (DEBUG) {printf("putOperatorOnStack(%s): getPrecedence(%s) <= getPrecedence(%s)\n", D(crtOp), D(crtOp), D(topOp));} //perform operation topOp between ACC and the number on the top of the RESULT_STACK performOperationWithACC(out); opPerformed = 1; }else{ if (DEBUG) {printf("putOperatorOnStack(%s): getPrecedence(%s) > getPrecedence(%s)\n", D(crtOp), D(crtOp), D(topOp));} break; } //fetch next operand topOp = topElement(&opStack); } if (opPerformed) { //store result from ACC into temporary variable strcpy(name, newName(VAR)); fprintf(out, "\tSTORE\t%s\n", name); if (DEBUG) {printf("putOperatorOnStack(): RES_PUSH(%s)\n", D(name));} push(createVElement(name), &resStack, -1); } if (DEBUG) {printf("putOperatorOnStack(%s): OP_PUSH(%s)\n", D(crtOp), D(crtOp));} push(createVElement(crtOp), &opStack, -1); }
//Infix to Prefix conversion void PREFIX_Convert(char infix[], char prestr[]) { int j,p; size_t n, i; char next ; char symbol; char temp; OPERANDSTACK opstk; resetStack(&opstk); n = strlen(infix); p = 0; for (i = n-1; n >= i; i--) { symbol = infix[i]; switch(symbol) { case ')': push(&opstk, symbol); break; case '(': while( (next=pop(&opstk)) != ')') { prestr[p++] = next; } break; case '+': case '-': case '*': case '/': case '%': case '^': while(!isEmpty(&opstk) && (getPrecedence(peek(&opstk)) > getPrecedence(symbol)) ) { prestr[p++] = pop(&opstk); } push(&opstk, symbol); break; //for an operand default: prestr[p++] = symbol; } } //end for while(!isEmpty(&opstk)) { prestr[p++] = pop(&opstk); } prestr[p] = '\0'; for(i = 0, j = p-2; i<j; i++, j--) { temp = prestr[i]; prestr[i] = prestr[j]; prestr[j] = temp; } prestr[p-1] = '\0'; }
void BinaryOperatorExpressionSyntax::stringify(stringstream* stream, int tabulation) { tabulate(stream, tabulation); if (_left->getPrecedence() > getPrecedence()) *stream << "("; _left->stringify(stream, 0); if (_left->getPrecedence() > getPrecedence()) *stream << ")"; *stream << " " << getOperatorSymbol() << " "; if (_right->getPrecedence() > getPrecedence()) *stream << "("; _right->stringify(stream, 0); if (_right->getPrecedence() > getPrecedence()) *stream << ")"; }
ASTNode *Parser::parseExpression(int precedence) { Token token = consume(); if (PrefixOps.find(token.Type) == PrefixOps.end()) { ParseError err(curTok().Begin,ParseError::unexpected_token_in_expression); err << Token::getHumanTokenName(token.Type) << token.String; // args err.setEnd(curTok().getEnd()); throw err; } Parselet::PrefixOp *prefix = PrefixOps[token.Type]; ASTNode *left = prefix->parse(this, token); //std::cout << "OPERATOR:" << Token::getTokenName(curTok().Type) << std::endl; while (precedence < getPrecedence()) { token = consume(); // getPrecedence returns 0 when op is not found so < should stop this from // being called assert(InfixOps.find(token.Type) != InfixOps.end() && "Tokens with negative precedences are not supported right now"); Parselet::InfixOp *infix = InfixOps[token.Type]; left = infix->parse(this, left, token); } return left; }
void PrettyPrinter::visitBinaryOpNode(BinaryOpNode *node) { if (getPrecedence(node) > getPrecedence(node->left())) m_out << "("; node->left()->visit(this); if (getPrecedence(node) > getPrecedence(node->left())) m_out << ")"; m_out << " " << tokenOp(node->kind()) << " "; if (getPrecedence(node) > getPrecedence(node->right())) m_out << "("; node->right()->visit(this); if (getPrecedence(node) > getPrecedence(node->right())) m_out << ")"; }
Node* Parser::parseBinaryExpr() { // BinaryExpr: Unary { OP Unary } stack<OperatorType> opStack; stack<Node*> nodeStack; auto _begin = parseUnaryExpr(); if (_begin == nullptr) return nullptr; nodeStack.push(_begin); while (Token::isOperator(lookahead)) { int prec = getPrecedence(Token::toOperator(lookahead)); if (opStack.empty() || prec > getPrecedence(opStack.top())) { opStack.push(Token::toOperator(lookahead)); nextToken(); auto l = parseUnaryExpr(); nodeStack.push(l); } else { while (!opStack.empty() && prec <= getPrecedence(opStack.top())) { Node *l1, *l2; l1 = nodeStack.top(); nodeStack.pop(); l2 = nodeStack.top(); nodeStack.pop(); nodeStack.push(make_node<BinaryExprNode>(opStack.top(), l2, l1)); opStack.pop(); } } } while (!opStack.empty()) { Node *l1, *l2; l1 = nodeStack.top(); nodeStack.pop(); l2 = nodeStack.top(); nodeStack.pop(); nodeStack.push(make_node<BinaryExprNode>(opStack.top(), l2, l1)); opStack.pop(); } return nodeStack.top(); }
//plant a tree. soon it will become part of a forest command_t make_command_tree(char *complete_command){ commandStack_t command_stack = createStack(); commandStack_t operator_stack = createStack(); int buff_pos = 0; char buff_char = '\0'; //char array to store simple commands as they come int simple_command_pos = 0; /* REGULAR_CHAR, //0 TOKEN_CHAR, //1 WHITESPACE_CHAR, //4 */ while ((buff_char = complete_command[buff_pos]) != '\0'){ //If a simple command, push it onto a command stack if (identify_char_type(buff_char) == REGULAR_CHAR){ char *simple_command = checked_malloc(1024 * sizeof(char)); memset(simple_command, '\0', 1024 * sizeof(char)); //add first valid character, and then add rest of the characters and whitespace in the simple command while (identify_char_type(buff_char) == REGULAR_CHAR || identify_char_type(buff_char) == WHITESPACE_CHAR /*||buff_char == '<' || buff_char == '>'*/){ simple_command[simple_command_pos] = buff_char; simple_command_pos++; buff_pos++; buff_char = complete_command[buff_pos]; } command_t new_cmd = createCommand(SIMPLE_COMMAND, simple_command); commandNode_t new_node = createNodeFromCommand(new_cmd); stackPush(command_stack, new_node); simple_command_pos =0; continue; } if (buff_char == '(') { command_t new_cmd = createCommand(SUBSHELL_OPEN, NULL); commandNode_t new_node = createNodeFromCommand(new_cmd); stackPush(operator_stack, new_node); buff_pos++; continue; } if (buff_char == '<') { //get the filename int k = buff_pos+1; int filename_startpos = k; while (complete_command[k] != '\0' && complete_command[k] != '>' && isOperator(complete_command[k]) != true && complete_command[k]!= ')') { k++; } int input_filename_size = k-filename_startpos; char* input_filename = (char*) checked_malloc((input_filename_size+1) * sizeof(char)); memset(input_filename, '\0', (input_filename_size+1) * sizeof(char)); int filename_pos =0; int l; for (l = filename_startpos; l<k; l++) { input_filename[filename_pos] = complete_command[l]; filename_pos++; } //if we're here we've read in the filename getTop(command_stack)->cmd->input = input_filename; buff_pos=k; continue; } if (buff_char=='>') { int k = buff_pos+1; int filename_startpos = k; while (complete_command[k] != '\0' && isOperator(complete_command[k]) != true && complete_command[k]!= ')') { k++; } int input_filename_size = k-filename_startpos; char* output_filename = (char*) checked_malloc((input_filename_size+1) * sizeof(char)); memset(output_filename, '\0', (input_filename_size+1) * sizeof(char)); int filename_pos =0; int l; for (l = filename_startpos; l<k; l++) { output_filename[filename_pos] = complete_command[l]; filename_pos++; } //if we're here, we've read in the full filename. getTop(command_stack)->cmd->output = output_filename; buff_pos=k; continue; } if (isOperator(buff_char) && operator_stack->top == NULL) { if (buff_char == '&') { command_t new_cmd = createCommand(AND_COMMAND, NULL); commandNode_t new_node = createNodeFromCommand(new_cmd); stackPush(operator_stack, new_node); buff_pos+=2; continue; } else if (buff_char == '|') { if (complete_command[buff_pos+1] == '|') { command_t new_cmd = createCommand(OR_COMMAND, NULL); commandNode_t new_node = createNodeFromCommand(new_cmd); stackPush(operator_stack, new_node); buff_pos+=2; continue; } else { command_t new_cmd = createCommand(PIPE_COMMAND, NULL); commandNode_t new_node = createNodeFromCommand(new_cmd); stackPush(operator_stack, new_node); buff_pos++; continue; } } else if (buff_char == ';') { command_t new_cmd = createCommand(SEQUENCE_COMMAND, NULL); commandNode_t new_node = createNodeFromCommand(new_cmd); stackPush(operator_stack, new_node); buff_pos++; continue; } } if (isOperator(buff_char) && operator_stack->top !=NULL) { command_t new_cmd; commandNode_t new_node; if (buff_char == '&') { new_cmd = createCommand(AND_COMMAND, NULL); new_node = createNodeFromCommand(new_cmd); buff_pos+=2; } else if (buff_char == '|') { if (complete_command[buff_pos+1] == '|') { new_cmd = createCommand(OR_COMMAND, NULL); new_node = createNodeFromCommand(new_cmd); buff_pos+=2; } else { new_cmd = createCommand(PIPE_COMMAND, NULL); new_node = createNodeFromCommand(new_cmd); buff_pos++; } } else { //(buff_char == ';') { new_cmd = createCommand(SEQUENCE_COMMAND, NULL); new_node = createNodeFromCommand(new_cmd); buff_pos++; } while ( getTop(operator_stack) != NULL && (getPrecedence(new_node) <= getPrecedence(getTop(operator_stack))) && getTop(operator_stack)->cmd->type != SUBSHELL_OPEN ) { commandNode_t popped = stackPop(operator_stack); commandNode_t operand1 = stackPop(command_stack); commandNode_t operand2 = stackPop(command_stack); //combine and then push onto stack commandNode_t combined_command = combine_commands(popped, operand1, operand2); stackPush(command_stack, combined_command); } stackPush(operator_stack, new_node); continue; } if (buff_char == ')') { commandNode_t poppedOperator; while ( ((poppedOperator = stackPop(operator_stack))->cmd->type) != SUBSHELL_OPEN ) { commandNode_t operand1 = stackPop(command_stack); commandNode_t operand2 = stackPop(command_stack); //combine and then push onto stack commandNode_t combined_command = combine_commands(poppedOperator, operand1, operand2); stackPush(command_stack, combined_command); } //at this point the popped operator should be a SUBSHELL_OPEN; get rid of it free(poppedOperator); command_t new_subshell = createCommand(SUBSHELL_COMMAND, NULL); new_subshell->u.subshell_command = stackPop(command_stack)->cmd; commandNode_t new_subshell_node = createNodeFromCommand(new_subshell); stackPush(command_stack, new_subshell_node); buff_pos++; continue; } //buff_pos++; } //end of buff_char while loop while (operator_stack -> top != NULL) { commandNode_t popped = stackPop(operator_stack); commandNode_t operand1 = stackPop(command_stack); commandNode_t operand2 = stackPop(command_stack); //combine and then push onto stack commandNode_t combined_command = combine_commands(popped, operand1, operand2); stackPush(command_stack, combined_command); } return getTop(command_stack)->cmd; }
int Parser::parse() { std::stack<Token> stack; ast.op = OP_HLT; ast.i = 0; lastTokenId = TOK_NONE; lastOp = -1; tok = scanner.getNextToken(); while (tok.id != TOK_EOF) { bool expectUnary = lastTokenId == TOK_LPAREN || lastTokenId == TOK_NONE || canBePrefix(lastTokenId) || canBeInfix(lastTokenId); bool expectExpr = lastTokenId == TOK_NONE || lastTokenId == TOK_LPAREN || canBePrefix(lastTokenId) || canBeInfix(lastTokenId); switch (tok.id) { default: raiseError("unknown token"); return 1; case TOK_ERROR: raiseError(tok.err); return 1; case TOK_PLUS: if (expectUnary) tok.id = TOK_UN_PLUS; else tok.id = TOK_OP_ADD; continue; case TOK_MINUS: if (expectUnary) tok.id = TOK_UN_NEG; else tok.id = TOK_OP_SUB; continue; case TOK_ARG: if (canBeValue(lastTokenId)) { raiseError("unexpected primary value"); return 1; } if (tok.i > UCHAR_MAX) { raiseError("argument number out of range"); return 1; } emitOp(OP_ARG, (unsigned char)(tok.i)); break; case TOK_LIT: if (canBeValue(lastTokenId)) { raiseError("unexpected primary value"); return 1; } emitOp(OP_CONST, tok.d); break; case TOK_F_PI: if (canBeValue(lastTokenId)) { raiseError("unexpected primary value"); return 1; } emitOp(OP_PI); break; case TOK_F_E: if (canBeValue(lastTokenId)) { raiseError("unexpected primary value"); return 1; } emitOp(OP_E); break; case TOK_UN_PLUS: // unary plus is a noop break; case TOK_LPAREN: if (!canBeFunction(lastTokenId) && !expectExpr) { raiseError("unexpected open parenthesis"); return 1; } stack.push(tok); break; case TOK_F_SQRT: case TOK_F_SIN: case TOK_F_COS: case TOK_F_TAN: case TOK_F_ASIN: case TOK_F_ACOS: case TOK_F_ATAN: case TOK_F_SINH: case TOK_F_COSH: case TOK_F_TANH: case TOK_F_ASINH: case TOK_F_ACOSH: case TOK_F_ATANH: case TOK_F_EXP: case TOK_F_LOG: case TOK_F_ERF: case TOK_F_ERFC: case TOK_F_ABS: case TOK_F_FLOOR: case TOK_F_CEIL: case TOK_F_ROUND: case TOK_F_TRUNC: case TOK_F_POW: case TOK_UN_NEG: if (canBeValue(lastTokenId)) { raiseError("unexpected prefix operator"); return 1; } stack.push(tok); break; case TOK_COMMA: while (stack.size() > 0 && stack.top().id != TOK_LPAREN) { emitOp(getOperator(stack.top().id)); stack.pop(); } if (stack.size() <= 0 || stack.top().id != TOK_LPAREN) { raiseError("misplaced comma"); return 1; } break; case TOK_RPAREN: while (stack.size() > 0 && stack.top().id != TOK_LPAREN) { emitOp(getOperator(stack.top().id)); stack.pop(); } if (stack.size() <= 0 || stack.top().id != TOK_LPAREN) { raiseError("mismatched parenthesis"); return 1; } stack.pop(); while (stack.size() > 0 && canBePrefix(stack.top().id)) { emitOp(getOperator(stack.top().id)); stack.pop(); } break; case TOK_OP_ADD: case TOK_OP_SUB: case TOK_OP_MUL: case TOK_OP_DIV: case TOK_OP_POW: if (!canBeValue(lastTokenId)) { raiseError("unexpected operator"); return 1; } while (stack.size() > 0 && canBeOperation(stack.top().id)) { if (isRightAssociative(tok.id)) { if (getPrecedence(tok.id) < getPrecedence(stack.top().id)) { emitOp(getOperator(stack.top().id)); stack.pop(); } else break; } else { if (getPrecedence(tok.id) <= getPrecedence(stack.top().id)) { emitOp(getOperator(stack.top().id)); stack.pop(); } else break; } } stack.push(tok); break; } lastTokenId = tok.id; tok = scanner.getNextToken(); } if (!canBeValue(lastTokenId)) { raiseError("unexpected program end"); return 1; } while (stack.size() > 0) { if (stack.top().id == TOK_LPAREN || stack.top().id == TOK_RPAREN) { raiseError("mismatched parenthesis"); return 1; } else { emitOp(getOperator(stack.top().id)); stack.pop(); } } return 0; }
/** read file */ static SCIP_RETCODE readFile( SCIP* scip, /**< SCIP data structure */ const char* filename, /**< name of input file */ SCIP_RCPSPDATA* rcpspdata /**< pointer to resources constrained project scheduling data */ ) { SCIP_FILE* fp; char buf[SM_MAX_LINELEN]; int lineno = 0; char* s; STATE state = NEXT; assert(filename != NULL); if( NULL == (fp = SCIPfopen(filename, "r")) ) { perror(filename); return SCIP_READERROR; } /* parse file line by line */ while( state != END && state != ERROR && (NULL != SCIPfgets(buf, sizeof(buf), fp)) ) { /* count line number */ lineno++; if( NULL != (s = strpbrk(buf, "*\r\n")) ) *s = '\0'; else { parseError(scip, lineno, "line truncated", NULL, &state); break; } s = buf; /* remove white space */ while(isspace(*s)) s++; /* skip empty lines */ if (*s == '\0') continue; if( state == NEXT ) { checkForNewSection(s, &state); } SCIPdebugMessage("input line: <%s>\n", s); switch( state ) { case ERROR: break; case NEXT: break; case NJOBS: SCIP_CALL( getNJobs(scip, lineno, s, &state, rcpspdata) ); break; case JOBS: SCIP_CALL( getJobs(scip, lineno, s, &state, rcpspdata) ); break; case NRESOURCES: SCIP_CALL( getNResources(scip, lineno, s, &state, rcpspdata) ); break; case RESOURCENAMES: SCIP_CALL( getResourcesNames(scip, lineno, s, &state, rcpspdata) ); break; case RESOURCECAPACITIES: SCIP_CALL( getResourcesCapacities(scip, lineno, s, &state, rcpspdata) ); break; case PRECEDENCES: SCIP_CALL( getPrecedence(scip, lineno, s, &state, rcpspdata) ); break; case END: parseError(scip, lineno, "additional characters after END", NULL, &state); break; default: SCIPerrorMessage("invalid reading state\n"); SCIPABORT(); } } SCIPfclose(fp); if( state != END && state != ERROR ) parseError(scip, lineno, "unexpected EOF", NULL, &state); if( state == ERROR ) return SCIP_READERROR; else return SCIP_OKAY; }