Ejemplo n.º 1
0
/**
 * Parses a Content-Length header value.
 */
int parse_header_content_length(struct parser *p) {
    char c, *buffer;
    int i, m, r;

    if (ready(p) < 3)
        return PARSING_WAIT;
    c = buffer_get(&(p->buffer), p->mark);

    for (m = 1; isdigit(c) || c == ' ' || c == '\t'; m++) {
        if (ready(p) < 3 + m)
            return PARSING_WAIT;
        c = buffer_get(&(p->buffer), p->mark + m);
    }

    buffer = buffer_copy(&(p->buffer), p->mark, m - 1);
    if (buffer == NULL) {
        p->error = E_MEMORY;
        return PARSING_ERROR;
    }
    advance_mark(p, m - 1);

    r = parse_constant(p, CRLF, 2);
    if (r != PARSING_DONE) {
        free(buffer);
        return r;
    }

    errno = 0;
    p->request.content_length = strtol(buffer, NULL, 10);
    free(buffer);
    return (errno == 0) ? PARSING_DONE : PARSING_ERROR;
}
Ejemplo n.º 2
0
				static IteratorT parse_meta(const char * prefix, IteratorT begin, IteratorT end) {
					IteratorT next = parse_constant(prefix, begin, end);

					if (next != begin) {
						return parse_string(parse_meta_character, next, end);
					} else {
						return begin;
					}
				}
Ejemplo n.º 3
0
void commandStore::execute(const std::vector<std::string>& cmd) {
    if (svmMemory->get_start()) {
        index_t rDest = parse_register(cmd[1]);
        index_t rSrc = parse_register(cmd[2]);
        address_t C = parse_constant(cmd[3]);
        execute(rDest, rSrc, C);
    }
    svmMemory->inc_program_counter();
}
Ejemplo n.º 4
0
/**
 * Parses the request method.
 */
int parse_request_method(struct parser *p) {
    char first;
    int r;

    if (ready(p) == 0)
        return PARSING_WAIT;

    first = buffer_get(&(p->buffer), p->mark);
    if (first == m_get[0]) {
        r = parse_constant(p, m_get, sizeof(m_get) - 1);
        if (r != PARSING_DONE)
            return r;

        p->request.method = METHOD_GET;
    } else if (first == m_head[0]) {
        r = parse_constant(p, m_head, sizeof(m_head) - 1);
        if (r != PARSING_DONE)
            return r;

        p->request.method = METHOD_HEAD;
    } else if (is_token_char(first)) {
        // other methods

        if (ready(p) < 2)
            return PARSING_WAIT;
        advance_mark(p, 1);

        while (is_token_char(buffer_get(&(p->buffer), p->mark))) {
            if (ready(p) < 2)
                return PARSING_WAIT;
            advance_mark(p, 1);
        }

        if (buffer_get(&(p->buffer), p->mark) != ' ')
            return PARSING_ERROR;
        advance_mark(p, 1);

        p->request.method = METHOD_OTHER;
    } else
        return PARSING_ERROR;

    return PARSING_DONE;
}
Ejemplo n.º 5
0
/**
 * Parses the HTTP version. Must be "HTTP/1.x".
 */
int parse_http_version(struct parser *p) {
    char c;
    int r;

    if (ready(p) < sizeof(http_version) + 1)
        return PARSING_WAIT;

    r = parse_constant(p, http_version, sizeof(http_version) - 2);
    if (r != PARSING_DONE)
        return r;

    c = buffer_get(&(p->buffer), p->mark);
    if (!isdigit(c))
        return PARSING_ERROR;
    p->request.version = c;
    advance_mark(p, 1);

    return parse_constant(p, CRLF, 2);
}
Ejemplo n.º 6
0
				static IteratorT parse_path(IteratorT begin, IteratorT end) {
					// This is optional, and signifies an absolute path.
					IteratorT absolute_begin = parse_constant("/", begin, end);

					IteratorT current = parse_string(parse_path_character, absolute_begin, end);

					if (current == begin)
						return begin;

					while (current != end) {
						IteratorT next = parse_constant("/", current, end);

						if (next == current)
							return current;

						current = parse_string(parse_path_character, next, end);
					}

					return current;
				}
Ejemplo n.º 7
0
				//   authority     = [ userinfo "@" ] host [ ":" port ]
				//   port          = *DIGIT
				static IteratorT parse_authority(IteratorT begin, IteratorT end, Authority & authority) {
					IteratorT user_info_begin = begin;

					IteratorT user_info_end = parse_string(parse_user_info_character, begin, end);
					IteratorT host_begin = parse_constant("@", user_info_end, end);

					// Can we parse the "@" symbol?
					if (host_begin != user_info_end) {
						// Valid user info was found:
						authority.user_info_begin = user_info_begin;
						authority.user_info_end = user_info_end;
					} else {
						host_begin = begin;
					}

					IteratorT host_end = parse_host(host_begin, end);

					if (host_end == host_begin) {
						// We can't continue as host is required.
						return host_end;
					}

					authority.host_begin = host_begin;
					authority.host_end = host_end;

					IteratorT port_begin = parse_constant(":", host_end, end);

					if (port_begin != host_end) {
						IteratorT port_end = parse_predicate(is_numeric, port_begin, end);

						authority.port_begin = port_begin;
						authority.port_end = port_end;

						return port_end;
					} else {
						return host_end;
					}
				}
Ejemplo n.º 8
0
				static IteratorT parse_scheme(IteratorT begin, IteratorT end) {
					IteratorT next = parse_predicate(is_alpha, begin, end);

					if (next == begin) {
						return begin;
					}

					next = parse_predicate(is_scheme_character, next, end);
					IteratorT scheme_end = parse_constant(":", next, end);

					if (scheme_end == next) {
						return begin;
					} else {
						return scheme_end;
					}
				}
Ejemplo n.º 9
0
/**
 * Parses a header value. Deprecated header line folding is not supported.
 */
int parse_header_value(struct parser *p) {
    char c;

    if (ready(p) < 3)
        return PARSING_WAIT;
    c = buffer_get(&(p->buffer), p->mark);

    while (isgraph(c) || c == ' ' || c == '\t') {
        advance_mark(p, 1);
        if (ready(p) < 3)
            return PARSING_WAIT;
        c = buffer_get(&(p->buffer), p->mark);
    }

    return parse_constant(p, CRLF, 2);
}
Ejemplo n.º 10
0
static void handle_num (const char *var, int *v_ptr, const char *val)

{
  char *end;

  if (*val == 'p' || *val == 'P')
    val++;
  else if (isalpha (*val))
    {
      *v_ptr = parse_constant (var, &val);
      return;
    }

  *v_ptr = strtol (val, &end, 0);
  if (*end)
    fprintf (stderr, "config: Variable '%s': ignoring trailing junk '%s' after value (%d)!\n", var, end, *v_ptr);
}
Ejemplo n.º 11
0
				static IteratorT parse_hierarchy(IteratorT begin, IteratorT end, Hierarchy & hierarchy) {
					// (//([^/?#]*))?
					IteratorT authority_begin = parse_constant("//", begin, end);
					IteratorT authority_end = authority_begin;

					if (authority_begin != begin) {
						authority_end = parse_authority(authority_begin, end, hierarchy.authority);

						hierarchy.authority_begin = authority_begin;
						hierarchy.authority_end = authority_end;
					}

					// ([^?#]*)
					hierarchy.path_begin = authority_end;
					hierarchy.path_end = parse_path(hierarchy.path_begin, end);

					return hierarchy.path_end;
				}
Ejemplo n.º 12
0
exparser::return_type exparser::loop(const std::string& s) {
    if (s.empty()) return return_false;
    
    if (debug) std::cout << "PARSING : " << s << std::endl;

    if (debug) std::cerr << "Try parenthesis" << std::endl;
    return_type parenthesis = parse_parenthesis(s);
    if (parenthesis) return parenthesis;
    
    if (debug) std::cerr << "Try constant" << std::endl;
    return_type constant = parse_constant(s);
    if (constant) return constant;
    
    if (debug) std::cerr << "Try variable" << std::endl;
    return_type variable = parse_variable(s);
    if (variable) return variable;
    
    if (debug) std::cerr << "Try plus" << std::endl;
    return_type plus = parse_plus(s);
    if (plus) return plus;
    
    if (debug) std::cerr << "Try minus" << std::endl;
    return_type minus = parse_minus(s);
    if (minus) return minus;

    if (debug) std::cerr << "Try multiply" << std::endl;
    return_type multiply = parse_multiply(s);
    if (multiply) return multiply;
    
    if (debug) std::cerr << "Try divide" << std::endl;
    return_type divide = parse_divide(s);
    if (divide) return divide;
    
    if (debug) std::cerr << "Try poewr" << std::endl;
    return_type power = parse_power(s);
    if (power) return power;
    
    if (debug) std::cerr << "Try function" << std::endl;
    return_type function = parse_function(s);
    if (function) return function;

    return return_false;
}
Ejemplo n.º 13
0
				//   URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
				//   ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
				//    12            3  4          5       6  7        8 9
				static IteratorT parse(IteratorT begin, IteratorT end, Components & components) {
					// (([^:/?#]+):)?
					IteratorT scheme_begin = begin;
					IteratorT scheme_end = parse_scheme(scheme_begin, end);

					if (scheme_end != scheme_begin) {
						components.scheme_begin = scheme_begin;
						components.scheme_end = scheme_end - 1;
					}

					IteratorT hierarchy_begin = parse_constant(":", scheme_end, end);
					IteratorT hierarchy_end = parse_hierarchy(hierarchy_begin, end, components.hierarchy);

					if (hierarchy_end == hierarchy_begin) {
						return hierarchy_begin;
					}

					components.hierarchy_begin = hierarchy_begin;
					components.hierarchy_end = hierarchy_end;

					IteratorT query_begin = hierarchy_end;
					IteratorT query_end = parse_meta("?", query_begin, end);

					if (query_end != query_begin) {
						components.query_begin = query_begin;
						components.query_end = query_end;
					}

					IteratorT fragment_begin = query_end;
					IteratorT fragment_end = parse_meta("#", fragment_begin, end);

					if (fragment_end != fragment_begin) {
						components.fragment_begin = fragment_begin;
						components.fragment_end = fragment_end;
					}

					components.complete = true;

					return fragment_end;
				}
Ejemplo n.º 14
0
instruction_ptr Parser::parse_value()
{
    int start_line = current_lexeme().line();
    
    if (match_current_lexeme(kSubtraction))
    {
        next_lexeme();
        
        instruction_ptr value = parse_value();
        if (!value)
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        return instruction_ptr(new ArithmeticOperationInstruction(start_line, kSub, instruction_ptr(new Constant(start_line, 0)), value));
    }
    
    if (match_current_lexeme(kLeftBracket))
    {
        next_lexeme();
        instruction_ptr expression = parse_expression();
        
        if (!match_current_lexeme(kRightBracket))
        {
            report_current_syntax_error();
            return instruction_ptr();
        }
        
        next_lexeme();
        
        return expression;
    }
    
    instruction_ptr value = parse_constant();
    if (!value)
        value = parse_function_call();
    
    return value;
}
Ejemplo n.º 15
0
/**
 * Parses HTTP headers. Only a few headers are actually processed, while most
 * values are discarded.
 */
int parse_headers(struct parser *p) {
    int r;

    while (TRUE) {
        switch (p->state) {
        case PARSING_HEADERS:
            r = parse_constant(p, CRLF, 2);
            if (r != PARSING_ERROR)
                return r;
            p->state = PARSING_HEADER_NAME;
            debug("parsing header");

        case PARSING_HEADER_NAME:
        case PARSING_HEADER_NAME_ANY:
            r = parse_header_name(p);
            if (r != PARSING_DONE)
                return r;
            debug("parsed header name");
        }

        switch (p->state) {
        case PARSING_HEADER_VALUE:
            r = parse_header_value(p);
            break;

        case PARSING_HEADER_CONTENT_LENGTH:
            r = parse_header_content_length(p);
            break;

        default:
            return PARSING_ERROR;
        }

        if (r != PARSING_DONE)
            return r;
        p->state = PARSING_HEADERS;
        debug("parsed header value");
    }
    return PARSING_DONE;
}
Ejemplo n.º 16
0
int add_constant(struct radeon_compiler *c, const char *const_str)
{
	float data[4];
	unsigned index;
	struct rc_constant_list *constants;
	struct rc_constant constant;

	if (!parse_constant(&index, data, const_str)) {
		return 0;
	}

	constants = &c->Program.Constants;
	if (constants->_Reserved < index) {
		struct rc_constant * newlist;

		constants->_Reserved = index + 100;

		newlist = malloc(sizeof(struct rc_constant) * constants->_Reserved);
		if (constants->Constants) {
			memcpy(newlist, constants->Constants,
				sizeof(struct rc_constant) *
					constants->_Reserved);
			free(constants->Constants);
		}

		constants->Constants = newlist;
	}

	memset(&constant, 0, sizeof(constant));
	constant.Type = RC_CONSTANT_IMMEDIATE;
	constant.Size = 4;
	memcpy(constant.u.Immediate, data, sizeof(float) * 4);
	constants->Constants[index] = constant;
	constants->Count = MAX2(constants->Count, index + 1);

	return 1;
}
Ejemplo n.º 17
0
cgc_ssize_t
cgc_tokenize(char *str, struct token *tokens)
{
    int ret;
    char c;
    struct token *token = tokens;

    while ((c = *str++)) {
        if (c == '_' || cgc_islower(c)) {
            if ((ret = parse_variable(str - 1, token)) < 0)
                return ret;

            str += ret - 1;
            token++;
            continue;
        }

        if (cgc_isdigit(c)) {
            if ((ret = parse_constant(str - 1, token)) < 0)
                return ret;

            str += ret - 1;
            token++;
            continue;
        }

        switch (c) {
        case '=':
            token->type = TOK_ASSIGNMENT;
            break;
        case '+':
            token->type = TOK_ADD;
            break;
        case '-':
            token->type = TOK_SUBTRACT;
            break;
        case '*':
            token->type = TOK_MULTIPLY;
            break;
        case '/':
            token->type = TOK_DIVIDE;
            break;
        case '~':
            token->type = TOK_NEGATE;
            break;
        case '&':
            token->type = TOK_ADDRESS_OF;
            break;
        case '$':
            token->type = TOK_DEREFERENCE;
            break;
        case '(':
            token->type = TOK_LEFT_PARENTHESIS;
            break;
        case ')':
            token->type = TOK_RIGHT_PARENTHESIS;
            break;
        case ' ':
            continue;
        default:
            return EXIT_FAILURE;
        }

        token++;
    }

    return token - tokens;
}
Ejemplo n.º 18
0
void get_token(Token *t)
{
    /* check if we need to free the previous string */
    if (t->token_string != NULL)
        {
            free(t->token_string);
            t->token_string = NULL;
        }

    enum Token_type a = peek_token_type();
    if (a != Tsymbol)
        {
            t->type = a;
            t->token_string = copy_token_string(token_index, token_index);
            token_index += 1;
            if (debug) fprintf(stderr, "next token: %s\n", t->token_string);
            return;
        }

    if (isalpha(input_buffer[token_index]))
        {
            int j;
            for (j = token_index; j < input_line_length; j++)
                {
                    if (isalpha(input_buffer[j])) continue;
                    if (isdigit(input_buffer[j])) continue;
                    if (input_buffer[j] == '_') continue;
                    if (input_buffer[j] == '.') continue;
                    /* not alpha, digit or underbar or period */
                    break;
                }
            /* symbol is from token_index to j-1 */
            t->token_string = copy_token_string(token_index, j-1);
            token_index = j;
            if (debug) fprintf(stderr, "next token: %s\n", t->token_string);

            /* search to see if this token is an opcode */
            opcode *op = search_opcode(t->token_string);
            if (op != NULL)
                {
                    t->type = Topcode;
                    t->op = op;
                    return;
                }

            /* search to see if this token is a known symbol */
            symbol *sy = search_symbol(t->token_string);
            if (sy != NULL)
                {
                    t->type = Tsymbol;
                    t->sy = sy;
                    t->value = sy->value;
                    return;
                }

            /* we have a symbol that is not currently defined */
            t->type = Tsymbol;
            t->sy = NULL;
            t->value = 0;
            return;
        }

    /* A numeric constant */
    else if (isdigit(input_buffer[token_index]) || (input_buffer[token_index] == '-'))
        {
            int value;
            if (parse_constant(t, &value))
                {
                    t->type = Tconstant;
                    t->value = value;
                    if (debug) fprintf(stderr, "next token: constant %d\n", t->value);
                    return;
                }
        }

    /* A character constant: '.'  */
    else if ((input_buffer[token_index] == '\'') && (input_buffer[token_index+2] == '\''))
        {
            t->type = Tconstant;
            t->value = input_buffer[token_index+1];
            t->token_string = malloc(4);
            t->token_string[0] = t->token_string[2] = '\'';
            t->token_string[1] = t->value;
            t->token_string[3] = '\0';
            token_index += 3;
            if (debug) fprintf(stderr, "next token: char constant %d (%c)\n", t->value, t->value);
            return;
        }

    /* and anything else is just illegal */
    /* should we advance the token_index here? */
    t->type = Tillegal;
    if (debug) fprintf(stderr, "next token: illegal\n");
    return;
}
Ejemplo n.º 19
0
Archivo: parser.c Proyecto: bieber/col
// Parses a set of constant arguments
struct list *parse_constant_args(struct lexer_state *lexer, 
                                 enum token_type close)
{
    struct value *arg = NULL;
    struct list *args = list_new();
    
    // First check for empty list
    lex(lexer);
    
    if(lexer->error == UNRECOGNIZED_TOKEN)
    {
        print_error(lexer, LEX_ERROR);
        clear_value_list(args);
        return NULL;
    }
    
    if(lexer->error == END_OF_INPUT)
    {
        print_error(lexer, UNEXPECTED_END);
        clear_value_list(args);
        return NULL;
    }

    // If we already have close token, just return empty list
    if(lexer->type == close)
        return args;
    else
        lexer_rewind(lexer);

    while(lexer->error == OK)
    {        
        // First parse a value and add it to the list
        arg = parse_constant(lexer);

        if(!arg)
        {
            clear_function_list(args);
            return NULL;
        }

        list_push_back(args, arg);

        // Now checking for a separator or end of the list
        lex(lexer);

        if(lexer->error == UNRECOGNIZED_TOKEN)
        {
            print_error(lexer, LEX_ERROR);
            clear_value_list(args);
            return NULL;
        }

        if(lexer->error == END_OF_INPUT)
        {
            print_error(lexer, UNEXPECTED_END);
            clear_value_list(args);
            return NULL;
        }

        if(lexer->type == close)
            break;

        // If the list is still open, we expect a separator
        if(lexer->type != SEPARATOR)
        {
            print_error(lexer, INVALID_ELEMENT);
            clear_value_list(args);
            return NULL;
        }
    }

    return args;
}
Ejemplo n.º 20
0
string
r_language_rep::get_color (tree t, int start, int end) {
  static bool setup_done= false;
  if (!setup_done) {
    r_color_setup_constants (colored);
    r_color_setup_keywords (colored);
    r_color_setup_otherlexeme (colored);
    setup_done= true;
  }

  static string none= "";
  if (start >= end) return none;
  string s= t->label;
  string r1=s(0,start) ;

  int pos=0;int opos;
  bool backquote= false;
  bool after_backquote;
  bool postfix= false;
  bool possible_function= true;
  bool possible_type= false;
  bool possible_class= false;
  bool possible_future_type= false;
  bool possible_future_function= true;
  bool possible_future_class= false;
  string type;
  bool is_markup;

#if 0
  // There isn't much point to the following, because its only effet is pos and type, and both are reset below.
  do {
    do {
      opos=pos;

      parse_string (s, pos);
      if (opos<pos) break;

      parse_comment_single_line (s, pos);
      if (opos < pos) {
	type= "comment";
	break;
      }

      pos++;
    } while(false);
  } while( pos<N(s) );
#endif 

  pos=0;
  do {
    type= none;
    do {
      after_backquote= backquote;
      possible_function= possible_future_function;
      possible_type= possible_future_type;
      possible_class= possible_future_class;
      opos= pos;

      parse_blanks (s, pos);
      if (opos<pos) break;

      parse_string (s, pos);
      if (opos<pos) {
	type= "string";
	backquote= false;
	postfix= false;
	possible_future_function= false;
	possible_future_type= false;
	possible_future_class= false;
	possible_type= false;
	break;
      }

      parse_number (s, pos);
      if (opos<pos) {
	type= "number";
	backquote= false;
	postfix= false;
	possible_future_function= false;
	possible_future_class= false;
	break;
      }

      parse_comment_single_line (s, pos);
      if (opos<pos) {
	type= "comment";
	backquote= false;
	postfix= false;
	possible_future_type= false;
	possible_type= false;
	break;
      }

      parse_modifier (colored, s, pos);
      if (opos<pos) {
	type="keyword";
	backquote= false;
	postfix= false;
	possible_future_type= false;
	possible_type= false;
	possible_function= false;
	break;
      }

      parse_postfix (colored, s, pos);
      if (opos<pos) {
	type="keyword";
	backquote= false;
	postfix= true;
	possible_future_type= false;
	possible_future_class= false;
	possible_type= false;
	possible_function= false;
	possible_future_class= false;
	break;
      }

      parse_class (colored, s, pos);
      if (opos<pos) {
	type= "keyword";
	backquote=false;
	postfix=false;
	possible_future_type= false;
	possible_type= false;
	possible_future_class=true;
	possible_future_function= false;
	break;
      }

      parse_keyword (colored, s, pos);
      if (opos<pos) {
	type= "keyword";
	backquote= false;
	postfix= false;
	possible_future_type= false;
	possible_type= false;
	possible_function= false;
	possible_future_function= false;
	possible_future_class= false;
	break;
      }

      parse_other_op_assign (colored, s, pos);  //not left parenthesis
      if (opos<pos) {
	type= "other_lexeme";// was
	type = "op assign" ;
	backquote= false;
	postfix= false;
	possible_function= false;
	possible_future_function= true;
	possible_future_type= false;
	possible_future_class= false;
	possible_type= false;
	break;
      }

      parse_other_op_index (colored, s, pos);  //not left parenthesis
      if (opos<pos) {
	type= "other_lexeme";// was
	type = "op index" ;
	backquote= false;
	postfix= false;
	possible_function= false;
	possible_future_function= true;
	possible_future_type= false;
	possible_future_class= false;
	possible_type= false;
	break;
      }

      parse_other_lexeme (colored, s, pos);  //not left parenthesis
      if (opos<pos) {
	type= "other_lexeme";// was
	type = "operator" ;
	backquote= false;
	postfix= false;
	possible_function= false;
	possible_future_function= true;
	possible_future_type= false;
	possible_future_class= false;
	possible_type= false;
	break;
      }

      parse_constant (colored, s, pos);
      if (opos<pos) {
	type= "constant";
	backquote= false;
	postfix= false;
	possible_future_function= false;
	possible_future_class= false;
	break;
      }


      parse_backquote (s, pos);
      if (opos<pos) {
	backquote= true;
	postfix= false;
	possible_future_function= false;
	possible_future_class= false;
	break;
      }

      parse_identifier_or_markup (colored, s, pos, postfix, is_markup);
      if (opos<pos) {
	if (is_markup) {type= "identifier_markup";} else type= "identifier";
	backquote= false;
	postfix= false;
	possible_future_function=false;
	possible_future_class= false;
	break;
      }

      parse_parenthesized (s, pos);
      // stops after well parenthesized ) or before  // or /{ or " or /"
      if (opos<pos && pos<=start) {
	type="left_parenthesis";
	backquote= false;
	postfix= false;
	possible_function= false;
	possible_future_function= true;
	possible_future_class= false;
	break;
      }
      if (opos<pos && possible_type==true)
	return "dark green";
      if (opos<pos && after_backquote)  
	return none;

      backquote= false;
      postfix= false;
      pos= opos;
      pos++;
    } while (false); // This while() is so that we can easily escape with break.
  } while (pos<=start);

  if (possible_type) return "dark green";
  if (type=="string") return "#a06040";
  if (type=="operator") return "red";
  if (type=="op assign") return "dark green";
  if (type=="op index") return "dark blue";
  if (type=="comment") return "brown";
  if (type=="keyword" && !after_backquote) return "#8020c0";
  if (type=="other_lexeme") return none;
  if (type=="constant") return "#2060c0";
  if (type=="number") return "#2060c0";
  if (type=="left_parenthesis") return none;
  if (type=="identifier" && !possible_function && !possible_class )  return none;
  if (type=="identifier_markup" && !possible_function && !possible_class ) return COLOR_MARKUP;

  if ( (type=="identifier" || type=="identifier_markup") && possible_function) {
    possible_function= false;
    do {
      do {
	opos=pos;
	parse_blanks (s, pos);
	if (opos<pos) break;

	parse_identifier (colored, s, pos,false);
	if (opos<pos) { possible_function= true; break; }

	parse_number (s, pos);
	if (opos<pos) { possible_function= true; break; }

	parse_constant (colored, s, pos);
	if (opos<pos) { possible_function= true; break; }

	parse_comment_single_line (s, pos);
	if (opos<pos) break;

	parse_parenthesized (s, pos);
	if (opos<pos) { possible_function= true; break; }

      } while (false);
    } while (opos != pos);

    if (!possible_function) {
      if (type=="identifier") {return none;} 
      else return COLOR_MARKUP; // type=="identifier_markup"
    } else do {
	do {
	  opos=pos;
	  parse_blanks (s, pos);
	  if (opos<pos) break;
	  parse_identifier (colored, s, pos,false);
	  if (opos<pos) break;
	  parse_number(s,pos);
	  if (opos<pos) break;
	  parse_constant (colored, s, pos);
	  if (opos<pos) break;
	  parse_comment_single_line(s,pos);
	  if (opos<pos) break;
	  parse_parenthesized (s, pos);
	  if (opos<pos) break;

	  if (type=="identifier") {return none;} 
	  else return COLOR_MARKUP;

	} while (false);
      }
      while (pos<N(s));
  } // type==identifier || type==identifier_markup && possible function

  if ( (type=="identifier" || type=="identifier_markup") && possible_class) {
    do {
      do {
	opos=pos;
	parse_blanks (s, pos);
	if (opos<pos) break;

	parse_identifier (colored, s, pos,false);
	if (opos<pos) break;

	parse_number(s,pos);
	if (opos<pos) break;

	parse_constant (colored, s, pos);
	if (opos<pos) break;

	parse_comment_single_line(s,pos);
	if (opos<pos) break;

	parse_parenthesized (s, pos);
	if (opos<pos) break;

	if (type=="identifier") {return none;} 
	else return COLOR_MARKUP;
      } while (false);
    }
    while (pos<N(s));
  }
  if (type=="identifier_markup") {return COLOR_MARKUP;}
  else return none;
}
Ejemplo n.º 21
0
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;
}