⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grammar.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (get_emits (&t, &s->m_emits, mapb))    {        spec_destroy (&s);        return 1;    }    *text = t;    *sp = s;    return 0;}/*    returns 0 on success,    returns 1 otherwise,*/static int get_rule (const byte **text, rule **ru, map_str *maps, map_byte *mapb){    const byte *t = *text;    rule *r = NULL;    rule_create (&r);    if (r == NULL)        return 1;    if (get_spec (&t, &r->m_specs, maps, mapb))    {        rule_destroy (&r);        return 1;    }    while (*t != ';')    {        byte *op = NULL;        spec *sp = NULL;        /* skip the dot that precedes "and" or "or" */        t++;        /* read "and" or "or" keyword */        if (get_identifier (&t, &op))        {            rule_destroy (&r);            return 1;        }        eat_spaces (&t);        if (r->m_oper == op_none)        {            /* .and */            if (str_equal ((byte *) "and", op))                r->m_oper = op_and;            /* .or */            else                r->m_oper = op_or;        }        mem_free ((void **) (void *) &op);        if (get_spec (&t, &sp, maps, mapb))        {            rule_destroy (&r);            return 1;        }        spec_append (&r->m_specs, sp);    }    /* skip the semicolon */    t++;    eat_spaces (&t);    *text = t;    *ru = r;    return 0;}/*    returns 0 on success,    returns 1 otherwise,*/static int update_dependency (map_rule *mapr, byte *symbol, rule **ru){    if (map_rule_find (&mapr, symbol, ru))        return 1;    (**ru).m_referenced = 1;    return 0;}/*    returns 0 on success,    returns 1 otherwise,*/static int update_dependencies (dict *di, map_rule *mapr, byte **syntax_symbol,    byte **string_symbol, map_byte *regbytes){    rule *rulez = di->m_rulez;    /* update dependecies for the root and lexer symbols */    if (update_dependency (mapr, *syntax_symbol, &di->m_syntax) ||        (*string_symbol != NULL && update_dependency (mapr, *string_symbol, &di->m_string)))        return 1;    mem_free ((void **) syntax_symbol);    mem_free ((void **) string_symbol);    /* update dependecies for the rest of the rules */    while (rulez)    {        spec *sp = rulez->m_specs;        /* iterate through all the specifiers */        while (sp)        {            /* update dependency for identifier */            if (sp->m_spec_type == st_identifier || sp->m_spec_type == st_identifier_loop)            {                if (update_dependency (mapr, sp->m_string, &sp->m_rule))                    return 1;                mem_free ((void **) &sp->m_string);            }            /* some errtexts reference to a rule */            if (sp->m_errtext && sp->m_errtext->m_token_name)            {                if (update_dependency (mapr, sp->m_errtext->m_token_name, &sp->m_errtext->m_token))                    return 1;                mem_free ((void **) &sp->m_errtext->m_token_name);            }            /* update dependency for condition */            if (sp->m_cond)            {                int i;                for (i = 0; i < 2; i++)                    if (sp->m_cond->m_operands[i].m_type == cot_regbyte)                    {                        sp->m_cond->m_operands[i].m_regbyte = map_byte_locate (&regbytes,                            sp->m_cond->m_operands[i].m_regname);                        if (sp->m_cond->m_operands[i].m_regbyte == NULL)                            return 1;                        mem_free ((void **) &sp->m_cond->m_operands[i].m_regname);                    }            }            /* update dependency for all .load instructions */            if (sp->m_emits)            {                emit *em = sp->m_emits;                while (em != NULL)                {                    if (em->m_emit_dest == ed_regbyte)                    {                        em->m_regbyte = map_byte_locate (&regbytes, em->m_regname);                        if (em->m_regbyte == NULL)                            return 1;                        mem_free ((void **) &em->m_regname);                    }                    em = em->m_next;                }            }            sp = sp->next;        }        rulez = rulez->next;    }    /* check for unreferenced symbols */    rulez = di->m_rulez;    while (rulez != NULL)    {        if (!rulez->m_referenced)        {            map_rule *ma = mapr;            while (ma)            {                if (ma->data == rulez)                {                    set_last_error (UNREFERENCED_IDENTIFIER, str_duplicate (ma->key), -1);                    return 1;                }                ma = ma->next;            }        }        rulez = rulez->next;    }    return 0;}static int satisfies_condition (cond *co, regbyte_ctx *ctx){    byte values[2];    int i;    if (co == NULL)        return 1;    for (i = 0; i < 2; i++)        switch (co->m_operands[i].m_type)        {        case cot_byte:            values[i] = co->m_operands[i].m_byte;            break;        case cot_regbyte:            values[i] = regbyte_ctx_extract (&ctx, co->m_operands[i].m_regbyte);            break;        }    switch (co->m_type)    {    case ct_equal:        return values[0] == values[1];    case ct_not_equal:        return values[0] != values[1];    }    return 0;}static void free_regbyte_ctx_stack (regbyte_ctx *top, regbyte_ctx *limit){    while (top != limit)    {        regbyte_ctx *rbc = top->m_prev;        regbyte_ctx_destroy (&top);        top = rbc;    }}typedef enum match_result_{    mr_not_matched,     /* the examined string does not match */    mr_matched,         /* the examined string matches */    mr_error_raised,    /* mr_not_matched + error has been raised */    mr_dont_emit,       /* used by identifier loops only */    mr_internal_error   /* an internal error has occured such as out of memory */} match_result;/* * This function does the main job. It parses the text and generates output data. */static match_resultmatch (dict *di, const byte *text, int *index, rule *ru, barray **ba, int filtering_string,       regbyte_ctx **rbc){   int ind = *index;    match_result status = mr_not_matched;    spec *sp = ru->m_specs;    regbyte_ctx *ctx = *rbc;    /* for every specifier in the rule */    while (sp)    {      int i, len, save_ind = ind;        barray *array = NULL;        if (satisfies_condition (sp->m_cond, ctx))        {            switch (sp->m_spec_type)            {            case st_identifier:                barray_create (&array);                if (array == NULL)                {                    free_regbyte_ctx_stack (ctx, *rbc);                    return mr_internal_error;                }                status = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);                if (status == mr_internal_error)                {                    free_regbyte_ctx_stack (ctx, *rbc);                    barray_destroy (&array);                    return mr_internal_error;                }                break;            case st_string:                len = str_length (sp->m_string);                /* prefilter the stream */                if (!filtering_string && di->m_string)                {                    barray *ba;               int filter_index = 0;                    match_result result;                    regbyte_ctx *null_ctx = NULL;                    barray_create (&ba);                    if (ba == NULL)                    {                        free_regbyte_ctx_stack (ctx, *rbc);                        return mr_internal_error;                    }                    result = match (di, text + ind, &filter_index, di->m_string, &ba, 1, &null_ctx);                    if (result == mr_internal_error)                    {                        free_regbyte_ctx_stack (ctx, *rbc);                        barray_destroy (&ba);                        return mr_internal_error;                    }                    if (result != mr_matched)                    {                        barray_destroy (&ba);                        status = mr_not_matched;                        break;                    }                    barray_destroy (&ba);                    if (filter_index != len || !str_equal_n (sp->m_string, text + ind, len))                    {                        status = mr_not_matched;                        break;                    }                    status = mr_matched;                    ind += len;                }                else                {                    status = mr_matched;                    for (i = 0; status == mr_matched && i < len; i++)                        if (text[ind + i] != sp->m_string[i])                            status = mr_not_matched;                    if (status == mr_matched)                        ind += len;                }                break;            case st_byte:                status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched;                if (status == mr_matched)                    ind++;                break;            case st_byte_range:                status = (text[ind] >= sp->m_byte[0] && text[ind] <= sp->m_byte[1]) ?                    mr_matched : mr_not_matched;                if (status == mr_matched)                    ind++;                break;            case st_true:                status = mr_matched;                break;            case st_false:                status = mr_not_matched;                break;            case st_debug:                status = ru->m_oper == op_and ? mr_matched : mr_not_matched;                break;            case st_identifier_loop:                barray_create (&array);                if (array == NULL)                {                    free_regbyte_ctx_stack (ctx, *rbc);                    return mr_internal_error;                }                status = mr_dont_emit;                for (;;)                {                    match_result result;                    save_ind = ind;                    result = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);                    if (result == mr_error_raised)                    {                        status = result;                        break;                    }                    else if (result == mr_matched)                    {                        if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx) ||                            barray_append (ba, &array))                        {                            free_regbyte_ctx_stack (ctx, *rbc);                            barray_destroy (&array);                            return mr_internal_error;                        }                        barray_destroy (&array);                        barray_create (&array);                        if (array == NULL)                        {                            free_regbyte_ctx_stack (ctx, *rbc);                            return mr_internal_error;                        }                    }                    else if (result == mr_internal_error)                    {                        free_regbyte_ctx_stack (ctx, *rbc);                        barray_destroy (&array);                        return mr_internal_error;                    }                    else                        break;                }                break;            }        }        else        {            status = mr_not_matched;        }        if (status == mr_error_raised)        {            free_regbyte_ctx_stack (ctx, *rbc);            barray_destroy (&array);            return mr_error_raised;        }        if (ru->m_oper == op_and && status != mr_matched && status != mr_dont_emit)        {            free_regbyte_ctx_stack (ctx, *rbc);            barray_destroy (&array);            if (sp->m_errtext)            {                set_last_error (sp->m_errtext->m_text, error_get_token (sp->m_errtext, di, text,                    ind), ind);                return mr_error_raised;            }            return mr_not_matched;        }        if (status == mr_matched)        {            if (sp->m_emits)                if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx))                {                    free_regbyte_ctx_stack (ctx, *rbc);                    barray_destroy (&array);                    return mr_internal_error;                }            if (array)                if (barray_append (ba, &array))                {                    free_regbyte_ctx_stack (ctx, *rbc);                    barray_destroy (&array);                    return mr_internal_error;                }        }        barray_destroy (&array);        /* if the rule operator is a logical or, we pick up the first matching specifier */        if (ru->m_oper == op_or && (status == mr_matched || status == mr_dont_emit))        {            *index = ind;            *rbc = ctx;            return mr_matched;        }        sp = sp->next;    }    /* everything went fine - all specifiers match up */    if (ru->m_oper == op_and && (status == mr_matched || status == mr_dont_emit))    {        *index = ind;        *rbc = ctx;        return mr_matched;    }    free_regbyte_ctx_stack (ctx, *rbc);    return mr_not_matched;}static match_resultfast_match (dict *di, const byte *text, int *index, rule *ru, int *_PP, bytepool *_BP,            int filtering_string, regbyte_ctx **rbc){   int ind = *index;    int _P = filtering_string ? 0 : *_PP;    int _P2;    match_result status = mr_not_matched;    spec *sp = ru->m_specs;    regbyte_ctx *ctx = *rbc;    /* for every specifier in the rule */    while (sp)    {      int i, len, save_ind = ind;        _P2 = _P + (sp->m_emits ? emit_size (sp->m_emits) : 0);        if (bytepool_reserve (_BP, _P2))        {            free_regbyte_ctx_stack (ctx, *rbc);            return mr_interna

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -