예제 #1
0
static void parse_cond( cheevos_cond_t* cond, const char** memaddr )
{
  const char* str = *memaddr;

  if ( *str == 'R' && str[ 1 ] == ':' )
  {
    cond->type = CHEEVOS_COND_TYPE_RESET_IF;
    str += 2;
  }
  else if ( *str == 'P' && str[ 1 ] == ':' )
  {
    cond->type = CHEEVOS_COND_TYPE_PAUSE_IF;
    str += 2;
  }
  else
  {
    cond->type = CHEEVOS_COND_TYPE_STANDARD;
  }

  parse_var( &cond->source, &str );
  cond->op = parse_operator( &str );
  parse_var( &cond->target, &str );
  cond->curr_hits = 0;
  cond->req_hits = read_hits( &str );

  *memaddr = str;
}
예제 #2
0
void Parser::compute_next() {
    if( !_alex.has_next() ) {
        _next = nullptr;
        return;
    }
    switch( _alex.peek().id ) {
        case Token::INCLUDE:
                _next = parse_include( _alex );
                return;
        case Token::CATEGORY:
                _next = parse_category( _alex );
                return;
        case Token::F:
        case Token::FX:
        case Token::FY:
        case Token::XF:
        case Token::YF:
        case Token::XFX:
        case Token::YFX:
        case Token::XFY:
                _next = parse_operator( _alex );
                return;
        default:
                throw parse_error( "Expected include, category or operator", _alex.peek() );
    }
}
예제 #3
0
iterator &iterator::next( void )
{
	_type = TOK_UNKNOWN;
	_value.clear();

	// Skip any whitespace
	while ( utf::is_pattern_whitespace( _c ) && _utf )
		next_utf();

	_whitespace.swap( _value );
	_type = TOK_UNKNOWN;
	_value.clear();

	if ( !_utf )
		return *this;

	_start.set( _utf );

	if ( _c == '{' )
	{
		// Code block
		_type = TOK_BLOCK_START;
		next_utf();
	}
	else if ( _c == '}' )
	{
		// Code block
		_type = TOK_BLOCK_END;
		next_utf();
	}
	else if ( _c == '(' )
	{
		// Expression ordering
		_type = TOK_PAREN_START;
		next_utf();
	}
	else if ( _c == ')' )
	{
		// Expression ordering
		_type = TOK_PAREN_END;
		next_utf();
	}
	else if ( _c == '[' )
	{
		// Expression ordering
		_type = TOK_MOD_START;
		next_utf();
	}
	else if ( _c == ']' )
	{
		// Expression ordering
		_type = TOK_MOD_END;
		next_utf();
	}
	else if ( _c == ',' )
	{
		// Argument separator
		_type = TOK_COMMA;
		next_utf();
	}
	else if ( _c == ';' )
	{
		// Statement terminator
		_type = TOK_EXPRESSION_END;
		next_utf();
	}
	else if ( _c == ':' )
	{
		// Separator
		_type = TOK_SEPARATOR;
		next_utf();
	}
	else if ( _c == '\"' )
		parse_string();
	else if ( _c == '\'' )
		parse_char();
	else if ( _c == 0x2AFD || _c == '#' ) // Double slash character or hash
	{
		_whitespace.push_back( _c );
		parse_comment();
	}
	else if ( _c == '/' || _c == 0x29F8 || _c == 0xFF0F || _c == 0x2044 ) // Slash, big slash, and fullwidth slash, fraction slash
	{
		char32_t comment_start = _c;
		skip_utf();
		if ( _c == comment_start || _c == U'*' )
			parse_comment();
		else
		{
			_value += comment_start;
			parse_operator();
		}
	}
	else if ( utf::is_identifier_start( _c ) )
		parse_identifier();
	else if ( utf::is_pattern_syntax( _c ) )
		parse_operator();
	else if ( utf::is_number_decimal( _c ) )
		parse_number();
	else
		next_utf();

	utf::nfc( _whitespace );
	utf::nfc( _value );

	_end.set( _utf );

	return *this;
}
예제 #4
0
/** Take a string (hopefully) containing an operator and either
		push it to the stack or eval it depending on precedence.
**/
int handle_op ( const char* op_str,
								Stack* op_stack, 
								Stack* num_stack)
{
#if DEBUG==1 
	cout << "Handling operator '" << op_str << "'." << endl;
#endif
	op_code new_op = -1;

	if (! (0 == op_str_len))
	{
		new_op = parse_operator (op_str, op_str_len, check_unm);
#if DEBUG==1
		cout << "Operator code is: " << new_op << endl;
#endif
	
		if (new_op == OP_CODE_ERR)
		{
			return PARSER_STATUS_NOP;
		}
		else
		{
#if DEBUG==1
			cout << "Comparing previous op, '" << op_stack -> top()
						<< "' with new op '" << new_op << "'." << endl;
			cout << "Precedence is: " << compare_prec (new_op,
							op_stack -> top() ) << endl;
#endif
	/* Only do if holding a low-precedence operator: */	
			while ((op_stack -> top() != OP_CODE_END) && !compare_prec (new_op, op_stack -> top()) )
			{
				double R_arg = num_stack -> top();
				num_stack -> pop();

				double L_arg = 0;
				if ( !is_unary ( op_stack -> top() ) )
				{
					if( num_stack -> empty() )
					{
						cerr << "Operations remain but not enough numbers to "
											"evaluate." << endl;
						return PARSER_STATUS_SYNTAX;
					}
#if DEBUG==1
					cout << "Operator is binary." <<endl;
#endif
					L_arg = num_stack -> top();
					num_stack -> pop();
				}

				double result = perform_op ( L_arg,
															R_arg,
															op_stack -> top(),
															status );
				last_result = result;
				op_stack -> pop();

#if DEBUG==1
				cout << "Result is: " << result << endl;
#endif
				num_stack -> push (result);
			}
	/* As long as we're not holding a right-paren */
			if (new_op != OP_CODE_RPN)
			{
#if DEBUG==1
				cout << "Pushing operator '" << new_op << "' to stack."<<endl;
#endif
				op_stack -> push( new_op );
			}
	/* only LPN has higher prec than RPN. Eliminate it. */
			else if ( OP_CODE_LPN == op_stack -> top() )
			{
				op_stack -> pop();
			}


#if DEBUG==1
			if( !op_stack -> empty() )
				cout << "Next up on stack: " << op_stack -> top() << endl;
#endif
		}
	}
	return PARSER_STATUS_GOOD;
}
예제 #5
0
파일: posty.c 프로젝트: falconindy/posty
int parse_expression(char *expr) {
  if (strlen(strtrim(expr)) == 0)
    return BREAK;

  char *token;
  static const char *operators = "+/*-%^";
  static const char *mfuncs = "|ln|sqrt|sin|cos|tan|asin|acos|atan|";
  static const char *constants = "|e|pi|";
  double operand;
  char *ptr;

  while ((token = strsep(&expr, " \n"))) {
    if (strlen(token) == 0) continue;

    if (*token == ':') /* precision specified */
      parse_precision(++token);
    else if (strchr(operators, *token) && strlen(token) == 1) { /* operator */
      if (stackptr - opstack < 2) {
        fprintf(stderr, "!! Malformed expression -- too few operands.\n");
        return CONTINUE;
      }

      if (parse_operator(*token) > 0) {
        return CONTINUE;
      }
    } else if ((ptr = strstr(mfuncs, strlower(token))) != NULL &&
              *(ptr - 1) == '|' && *(ptr + strlen(token)) == '|') {
      /* validated trig function */
      if (stackptr - opstack < 1) {
        fprintf(stderr, "!! Malformed expression -- too few operands.\n");
        return CONTINUE;
      }
      parse_mfunc(token);
    } else if ((ptr = strstr(constants, strlower(token))) != NULL &&
              *(ptr - 1) == '|' && *(ptr + strlen(token)) == '|') {
      /* validated constant */
      parse_constant(token);
    } else { /* it's an operand, or it's bad input */
      if (parse_operand(token, &operand) > 0) /* parsing failed on bad input */
        return CONTINUE;

      if (stackptr == &opstack[STACK_SIZE]) { /* stack overflow */
        fprintf(stderr, "!! Stack overflow. Expression too large.\n");
        return CONTINUE;
      }

      *stackptr++ = operand;
    }
  }

  if (stackptr - opstack > 1)
    fprintf(stderr, "!! Malformed expression -- too many operands.\n");
  else if (stackptr - opstack == 1) {
    if (verbose >= 1)
      printf(" = %.*f\n", precision, *--stackptr);
    else
      printf("%.*f\n", precision, *--stackptr);
  }

  return CONTINUE;
}