コード例 #1
0
float parse_float(char** c)
{
    char* curr = *c;

    while(is_whitespace(*curr))
        curr++;
    
    if(!is_number_char(*curr) && *curr != '-' && *curr != '.')
        return 0.0f;

    char* start = curr;
    
    while(is_number_char(*curr) || *curr == '.' || *curr == '-')
    {
        curr++;
    }

    char* buffer = (char*)alloca((curr + 1 - start) * sizeof(char));
    strncpy(buffer, start, (curr - start));
    buffer[curr-start] = '\0';

    *c = curr;

    return atof(buffer);
}
コード例 #2
0
int parse_int(char** c)
{
    char* curr = *c;

    while(is_whitespace(*curr))
        curr++;
    
    if(!is_number_char(*curr))
        return 0;

    char* start = curr;
    
    while(is_number_char(*curr))
    {
        curr++;
    }

    char* buffer = (char*)alloca((curr + 1 - start) * sizeof(char));
    strncpy(buffer, start, (curr - start));
    buffer[curr-start] = '\0';

    *c = curr;

    return strtol(buffer, NULL, 10);
}
コード例 #3
0
ファイル: parser.cpp プロジェクト: Arelius/ploy
pointer parse_expr(parser* parse)
{
    eat_whitespace(parse);
    pointer ret_car;
    pointer ret_cdr;
    switch(*parse->curr)
    {
    case '(':
        parse->curr++;
        ret_car = parse_expr(parse);
        ret_cdr = parse_expr(parse);
        return create_pair(ret_car, ret_cdr);
    case '"':
        ret_car = parse_string(parse);
        ret_cdr = parse_expr(parse);
        return create_pair(ret_car, ret_cdr);
    case '\'':
        parse->curr++;
        ret_car = parse_quote(parse);
        ret_cdr = parse_expr(parse);
        return create_pair(ret_car, ret_cdr);
    case ')':
        parse->curr++;
        return NIL;
    case '+': case '-': case 'b':
        ret_car = parse_number_or_symbol(parse);
        ret_cdr = parse_expr(parse);
        return create_pair(ret_car, ret_cdr);
    case '.':
        return parse_number_or_pair(parse);
    case '\\':
        parse->curr++;
        ret_car = create_char(*(parse->curr++));
        ret_cdr = parse_expr(parse);
        return create_pair(ret_car, ret_cdr);
    case ';':
        while(!is_newline(*parse->curr) && *parse->curr != '\0')
            parse->curr++;
        return parse_expr(parse);
    case 0:
        return NIL;
    default:
        if(is_number_char(*parse->curr))
        {
            ret_car = parse_number(parse);
            ret_cdr = parse_expr(parse);
            return create_pair(ret_car, ret_cdr);
        }
        else if(is_symbol_char(*parse->curr))
        {
            ret_car = parse_symbol(parse);
            ret_cdr = parse_expr(parse);
            return create_pair(ret_car, ret_cdr);
        }
        else
            return parser_error(parse, "Unexpected char in expression.");

    }
    parse->curr++;
}
コード例 #4
0
ファイル: parser.cpp プロジェクト: Arelius/ploy
pointer parse_quote(parser* parse)
{
    if(is_whitespace(*parse->curr))
        return parser_error(parse, "unexpected whitespace after quote.");

    switch(*parse->curr)
    {
    case '(':
        return create_pair(create_symbol(parse->symbols, "QUOTE"), parse_expr(parse));
    default:
        if(is_symbol_char(*parse->curr) && !is_number_char(*parse->curr))
            return create_pair(create_symbol(parse->symbols, "QUOTE"), parse_symbol(parse));
        else
            return parser_error(parse, "Unexpected token after quote.");

    }

}
コード例 #5
0
ファイル: parser.cpp プロジェクト: Arelius/ploy
pointer parse_number(parser* parse)
{
    size_t len = 0;
    bool isFloat = false;
    bool isHex = false;
    bool isBinary = false;

    const char* Start = parse->curr;

    while(!is_delimiter(*parse->curr))
    {
        if(*parse->curr == '.')
            isFloat = true;

        if(is_number_char(*parse->curr) ||
           (isHex && is_extended_hex_char(*parse->curr)))
            len++;
        else if(len == 1 &&
                *parse->curr == 'x' &&
                *Start == '0')
        {
            len++;
            isHex = true;
        }
        else if(len == 0 && *parse->curr == 'b')
            isBinary = true;
        else
            return parser_error(parse, "Unexpected char '%c' in number literal.", *parse->curr);
        parse->curr++;
    }

    {
        int TotalIs = isHex + isBinary + isFloat;
        if(TotalIs > true)
        {
            char* buffer = new char[len+1];

            strncpy(buffer, Start, len);
            buffer[len] = '\0';
            parser_error(parse, "Unexpected number literal: %s.", buffer);
            delete buffer;
            return NIL;

        }
    }

    if(isFloat)
    {
        char* buffer = new char[len+1];

        strncpy(buffer, Start, len);
        buffer[len] = '\0';

        float ret = atof(buffer);
        delete buffer;

        return create_real(ret);
    }
    else
    {
        // Might be smart to use a buffer here, in case strtol doesn't see all delimiters as we do.
        int ret;
        if(isHex)
            ret  = strtol(Start + 2, NULL,  16);
        else if(isBinary)
            ret = strtol(Start + 1, NULL, 2);
        else
            ret = strtol(Start, NULL, 10);

        return create_int(ret);
    }


}
コード例 #6
0
ファイル: write.c プロジェクト: nyue/graphviz-cmake
/* _agstrcanon:
 * Canonicalize ordinary strings. 
 * Assumes buf is large enough to hold output.
 */
static char *_agstrcanon(char *arg, char *buf)
{
    char *s, *p;
    unsigned char uc;
    int cnt = 0;
    int needs_quotes = FALSE;
    int maybe_num;
    int backslash_pending = FALSE;
    static const char *tokenlist[]	/* must agree with scan.l */
	= { "node", "edge", "strict", "graph", "digraph", "subgraph",
	NIL(char *)
    };
    const char **tok;

    if (EMPTY(arg))
	return "\"\"";
    s = arg;
    p = buf;
    *p++ = '\"';
    uc = *(unsigned char *) s++;
    maybe_num = is_number_char(uc);
    while (uc) {
	if (uc == '\"') {
	    *p++ = '\\';
	    needs_quotes = TRUE;
	} else {
	    if (!ISALNUM(uc))
		needs_quotes = TRUE;
	    else if (maybe_num && !is_number_char(uc))
		needs_quotes = TRUE;
	}
	*p++ = (char) uc;
	uc = *(unsigned char *) s++;
	cnt++;
	
        if (uc && backslash_pending && !((is_number_char(p[-1]) || isalpha(p[-1]) || (p[-1] == '\\')) && (is_number_char(uc) || isalpha(uc)))) {
            *p++ = '\\';
            *p++ = '\n';
            needs_quotes = TRUE;
            backslash_pending = FALSE;
	    cnt = 0;
        } else if (uc && (cnt >= MAX_OUTPUTLINE)) {
            if (!((is_number_char(p[-1]) || isalpha(p[-1]) || (p[-1] == '\\')) && (is_number_char(uc) || isalpha(uc)))) {
	        *p++ = '\\';
    	        *p++ = '\n';
	        needs_quotes = TRUE;
		cnt = 0;
            } else {
                backslash_pending = TRUE;
            }
	}
    }
    *p++ = '\"';
    *p = '\0';
    if (needs_quotes)
	return buf;

    /* Use quotes to protect tokens (example, a node named "node") */
    /* It would be great if it were easier to use flex here. */
    for (tok = tokenlist; *tok; tok++)
	if (!strcasecmp(*tok, arg))
	    return buf;
    return arg;
}