int rel(){ int t,t1,t2; t1 = _expr(); switch(look->tag){ case '<': t = temp++; move(); t2 = _expr(); gen("t%d = t%d < t%d\n",t,t1,t2); return t; case LE: t = temp++; move(); t2 = _expr(); gen("t%d = t%d <= t%d\n",t,t1,t2); return t; case GE: t = temp++; move(); t2 = _expr(); gen("t%d = t%d >= t%d\n",t,t1,t2); return t; case '>': t = temp++; move(); t2 = _expr(); gen("t%d = t%d > t%d\n",t,t1,t2); return t; default: return t1; } }
bool Parser::parse() { _result = _expr(); TokenType t = _token(); if (t != TT_EOF) { notifyListeners("Syntax error: unparsed data at end of source"); _success = false; } return _success; }
int lang_constexpr(struct symbols_t *sl, struct token_t *token, int64_t *value) { if (!token_get(token, TOKEN_TYPE_CURLY_OPEN, TOKEN_NEXT)) return -1; /* * Expression syntax. * * EXPR = EXPR, "|", OR_OPD | OR_OPD * OR_OPD = OR_OPD, "^", XOR_OPD | XOR_OPD * XOR_OPD = XOR_OPD, "&", AND_OPD | AND_OPD * AND_OPD = AND_OPD, "<<", SHIFT_OPD | AND_OPD, ">>", SHIFT_OPD | SHIFT_OPD * SHIFT_OPD = SHIFT_OPD, "+", ADD_OPD | SHIFT_OPD, "-", ADD_OPD | ADD_OPD * ADD_OPD = ADD_OPD, "*", MUL_OPD | ADD_OPD, "/", MUL_OPD | ADD_OPD, "%", MUL_OPD | MUL_OPD * MUL_OPD = "~", MUL_OPD | NOT_OPD * NOT_OPD = NUMBER | SYMBOL | "(", EXPR, ")" * * Eliminate of left recursion. * * EXPR = OR_OPD, EXPRR * EXPRR = "|", OR_OPD, EXPRR | 0 * OR_OPD = XOR_OPD, OR_OPDR * OR_OPDR = "^", XOR_OPD, OR_OPDR | 0 * XOR_OPD = AND_OPD, XOR_OPDR * XOR_OPDR = "&", AND_OPD, XOR_OPDR | 0 * AND_OPD = SHIFT_OPD, AND_OPDR * AND_OPDR = "<<", SHIFT_OPD, AND_OPDR | ">>", SHIFT_OPD, AND_OPDR | 0 * SHIFT_OPD = ADD_OPD, SHIFT_OPDR * SHIFT_OPDR = "+", ADD_OPD, SHIFT_OPDR | "-", ADD_OPD, SHIFT_OPDR | 0 * ADD_OPD = MUL_OPD, ADD_OPDR * ADD_OPDR = "*", MUL_OPD, ADD_OPDR | "/", MUL_OPD, ADD_OPDR |"%", MUL_OPD, ADD_OPDR | 0 * MUL_OPD = "!", NOT_OPD | NOT_OPD * NOT_OPD = NUMBER | SYMBOL | "(", EXPR, ")" */ _exprstack_flush(); _expr(sl, token); *value = _exprstack_pop(); if (!token_get(token, TOKEN_TYPE_CURLY_CLOSE, TOKEN_NEXT)) { debug_emsg("Missing \"}\" in expr"); token_print_rollback(token); app_close(APP_EXITCODE_ERROR); } token_drop(token); return 0; }
static void _not_opd(struct symbols_t *sl, struct token_t *token) { char *tname; PRINTF("%s" NL, __FUNCTION__); if ((tname = token_get(token, TOKEN_TYPE_NUMBER, TOKEN_NEXT))) { int64_t value; PRINTF("NUM %s" NL, tname); if (lang_util_str2num(tname, &value) < 0) { token_print_rollback(token); app_close(APP_EXITCODE_ERROR); } _exprstack_push(value); } else if ((tname = token_get(token, TOKEN_TYPE_SYMBOL, TOKEN_NEXT))) { struct symbol_t *s; int64_t value; s = symbol_get_const(sl, tname, &value); if (!s) { debug_emsgf("Symbol not found", "%s" NL, tname); token_print_rollback(token); app_close(APP_EXITCODE_ERROR); } _exprstack_push(value); } else if (token_get(token, TOKEN_TYPE_ROUND_OPEN, TOKEN_NEXT)) { _expr(sl, token); if (!token_get(token, TOKEN_TYPE_ROUND_CLOSE, TOKEN_NEXT)) { debug_emsg("Missing \")\" in expr"); token_print_rollback(token); app_close(APP_EXITCODE_ERROR); } } else { debug_emsg("Empty expression"); token_print_rollback(token); app_close(APP_EXITCODE_ERROR); } }
int Parser::_factor() { int value; TokenType t = _token(); // Factor can be a ( expr ) if (t == TT_LPAREN) { _scanner.advance(); value = _expr(); t = _token(); if (t == TT_RPAREN) { _scanner.advance(); return value; } else { notifyListeners("Syntax error: expecting a ')'"); _success = false; return 0; } } std::stringstream ss; // Factor can be begin w/ a '+' or '-' to indicate sign. if (t == TT_PLUS || t == TT_MINUS) { ss << _scanner.next(); _scanner.advance(); t = _token(); } // A number is expected. if (t == TT_NUMBER) { _parseNumber(); assert(!_buffer.empty()); ss << _buffer; ss >> value; assert(ss.eof()); return value; }
double WidgetCalc::_factor(const std::string& str, unsigned *idx) { double result; int sign = 1; if (str[*idx] == '-') { sign = -1; ++*idx; } if (str[*idx] == '(') { ++*idx; result = _expr(str, idx); if (str[*idx] != ')') { Logger::warning( "!!! WARNING: Brackets unbalanced!"); return 0; } ++*idx; } else result = _number(str, idx); if (str[*idx] == '^') { ++*idx; result = pow(result, _factor(str, idx)); } return sign * result; }
double WidgetCalc::eval(const std::string& str) { unsigned i = 0; return _expr(str, &i); }