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

📄 grammar.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:

    map_byte_create (&m);
    if (m == NULL)
        return 1;

    if (get_identifier (&t, &m->key))
    {
        map_byte_destroy (&m);
        return 1;
    }
    eat_spaces (&t);

    if (*t == '\'')
    {
        byte *c;

        if (get_string (&t, &c))
        {
            map_byte_destroy (&m);
            return 1;
        }

        m->data = (byte) c[0];
        mem_free ((void **) (void *) &c);
    }
    else if (t[0] == '0' && (t[1] == 'x' || t[1] == 'X'))
    {
        /* skip HEX "0x" or "0X" prefix */
        t += 2;
        m->data = (byte) hex_convert (&t);
    }
    else
    {
        m->data = (byte) dec_convert (&t);
    }

    eat_spaces (&t);

    *text = t;
    *ma = m;
    return 0;
}

/*
    gets regbyte declaration, the syntax is:
    ".regbyte" " " <symbol> " " (("0x" | "0X") <hex_value>) | <dec_value> | <character>
    assumes that *text already points to <symbol>,
    returns 0 if regbyte is successfully read,
    returns 1 otherwise
*/
static int get_regbyte (const byte **text, map_byte **ma)
{
    /* pass it to the emtcode parser as it has the same syntax starting at <symbol> */
    return get_emtcode (text, ma);
}

/*
    returns 0 on success,
    returns 1 otherwise
*/
static int get_errtext (const byte **text, map_str **ma)
{
    const byte *t = *text;
    map_str *m = NULL;

    map_str_create (&m);
    if (m == NULL)
        return 1;

    if (get_identifier (&t, &m->key))
    {
        map_str_destroy (&m);
        return 1;
    }
    eat_spaces (&t);

    if (get_string (&t, &m->data))
    {
        map_str_destroy (&m);
        return 1;
    }
    eat_spaces (&t);

    *text = t;
    *ma = m;
    return 0;
}

/*
    returns 0 on success,
    returns 1 otherwise,
*/
static int get_error (const byte **text, error **er, map_str *maps)
{
    const byte *t = *text;
    byte *temp = NULL;

    if (*t != '.')
        return 0;

    t++;
    if (get_identifier (&t, &temp))
        return 1;
    eat_spaces (&t);

    if (!str_equal ((byte *) "error", temp))
    {
        mem_free ((void **) (void *) &temp);
        return 0;
    }

    mem_free ((void **) (void *) &temp);

    error_create (er);
    if (*er == NULL)
        return 1;

    if (*t == '\"')
    {
        if (get_string (&t, &(**er).m_text))
        {
            error_destroy (er);
            return 1;
        }
        eat_spaces (&t);
    }
    else
    {
        if (get_identifier (&t, &temp))
        {
            error_destroy (er);
            return 1;
        }
        eat_spaces (&t);

        if (map_str_find (&maps, temp, &(**er).m_text))
        {
            mem_free ((void **) (void *) &temp);
            error_destroy (er);
            return 1;
        }

        mem_free ((void **) (void *) &temp);
    }

    /* try to extract "token" from "...$token$..." */
    {
        byte *processed = NULL;
        unsigned int len = 0, i = 0;

        if (string_grow (&processed, &len, '\0'))
        {
            error_destroy (er);
            return 1;
        }

        while (i < str_length ((**er).m_text))
        {
            /* check if the dollar sign is repeated - if so skip it */
            if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$')
            {
                if (string_grow (&processed, &len, '$'))
                {
                    mem_free ((void **) (void *) &processed);
                    error_destroy (er);
                    return 1;
                }

                i += 2;
            }
            else if ((**er).m_text[i] != '$')
            {
                if (string_grow (&processed, &len, (**er).m_text[i]))
                {
                    mem_free ((void **) (void *) &processed);
                    error_destroy (er);
                    return 1;
                }

                i++;
            }
            else
            {
                if (string_grow (&processed, &len, '$'))
                {
                    mem_free ((void **) (void *) &processed);
                    error_destroy (er);
                    return 1;
                }

                {
                    /* length of token being extracted */
                    unsigned int tlen = 0;

                    if (string_grow (&(**er).m_token_name, &tlen, '\0'))
                    {
                        mem_free ((void **) (void *) &processed);
                        error_destroy (er);
                        return 1;
                    }

                    /* skip the dollar sign */
                    i++;

                    while ((**er).m_text[i] != '$')
                    {
                        if (string_grow (&(**er).m_token_name, &tlen, (**er).m_text[i]))
                        {
                            mem_free ((void **) (void *) &processed);
                            error_destroy (er);
                            return 1;
                        }

                        i++;
                    }

                    /* skip the dollar sign */
                    i++;
                }
            }
        }

        mem_free ((void **) &(**er).m_text);
        (**er).m_text = processed;
    }

    *text = t;
    return 0;
}

/*
    returns 0 on success,
    returns 1 otherwise,
*/
static int get_emits (const byte **text, emit **em, map_byte *mapb)
{
    const byte *t = *text;
    byte *temp = NULL;
    emit *e = NULL;
    emit_dest dest;

    if (*t != '.')
        return 0;

    t++;
    if (get_identifier (&t, &temp))
        return 1;
    eat_spaces (&t);

    /* .emit */
    if (str_equal ((byte *) "emit", temp))
        dest = ed_output;
    /* .load */
    else if (str_equal ((byte *) "load", temp))
        dest = ed_regbyte;
    else
    {
        mem_free ((void **) (void *) &temp);
        return 0;
    }

    mem_free ((void **) (void *) &temp);

    emit_create (&e);
    if (e == NULL)
        return 1;

    e->m_emit_dest = dest;

    if (dest == ed_regbyte)
    {
        if (get_identifier (&t, &e->m_regname))
        {
            emit_destroy (&e);
            return 1;
        }
        eat_spaces (&t);
    }

    /* 0xNN */
    if (*t == '0' && (t[1] == 'x' || t[1] == 'X'))
    {
        t += 2;
        e->m_byte = (byte) hex_convert (&t);

        e->m_emit_type = et_byte;
    }
    /* NNN */
    else if (*t >= '0' && *t <= '9')
    {
        e->m_byte = (byte) dec_convert (&t);

        e->m_emit_type = et_byte;
    }
    /* * */
    else if (*t == '*')
    {
        t++;

        e->m_emit_type = et_stream;
    }
    /* $ */
    else if (*t == '$')
    {
        t++;

        e->m_emit_type = et_position;
    }
    /* 'c' */
    else if (*t == '\'')
    {
        if (get_string (&t, &temp))
        {
            emit_destroy (&e);
            return 1;
        }
        e->m_byte = (byte) temp[0];

        mem_free ((void **) (void *) &temp);

        e->m_emit_type = et_byte;
    }
    else
    {
        if (get_identifier (&t, &temp))
        {
            emit_destroy (&e);
            return 1;
        }

        if (map_byte_find (&mapb, temp, &e->m_byte))
        {
            mem_free ((void **) (void *) &temp);
            emit_destroy (&e);
            return 1;
        }

        mem_free ((void **) (void *) &temp);

        e->m_emit_type = et_byte;
    }

    eat_spaces (&t);

    if (get_emits (&t, &e->m_next, mapb))
    {
        emit_destroy (&e);
        return 1;
    }

    *text = t;
    *em = e;
    return 0;
}

/*
    returns 0 on success,
    returns 1 otherwise,
*/
static int get_spec (const byte **text, spec **sp, map_str *maps, map_byte *mapb)
{
    const byte *t = *text;
    spec *s = NULL;

    spec_create (&s);
    if (s == NULL)
        return 1;

    /* first - read optional .if statement */
    if (*t == '.')
    {
        const byte *u = t;
        byte *keyword = NULL;

        /* skip the dot */
        u++;

        if (get_identifier (&u, &keyword))
        {
            spec_destroy (&s);
            return 1;
        }

        /* .if */
        if (str_equal ((byte *) "if", keyword))
        {
            cond_create (&s->m_cond);
            if (s->m_cond == NULL)
            {
                spec_destroy (&s);
                return 1;
            }

            /* skip the left paren */
            eat_spaces (&u);
            u++;

            /* get the left operand */
            eat_spaces (&u);
            if (get_identifier (&u, &s->m_cond->m_operands[0].m_regname))
            {
                spec_destroy (&s);
                return 1;
            }
            s->m_cond->m_operands[0].m_type = cot_regbyte;

            /* get the operator (!= or ==) */
            eat_spaces (&u);
            if (*u == '!')
                s->m_cond->m_type = ct_not_equal;
            else
                s->m_cond->m_type = ct_equal;
            u += 2;
            eat_spaces (&u);

            if (u[0] == '0' && (u[1] == 'x' || u[1] == 'X'))
            {
                /* skip the 0x prefix */
                u += 2;

                /* get the right operand */
                s->m_cond->m_operands[1].m_byte = hex_convert (&u);
                s->m_cond->m_operands[1].m_type = cot_byte;
            }
            else /*if (*u >= '0' && *u <= '9')*/
            {
                /* get the right operand */
                s->m_cond->m_operands[1].m_byte = dec_convert (&u);
                s->m_cond->m_operands[1].m_type = cot_byte;
            }

            /* skip the right paren */
            eat_spaces (&u);
            u++;

            eat_spaces (&u);

            t = u;
        }

        mem_free ((void **) (void *) &keyword);
    }

    if (*t == '\'')
    {
        byte *temp = NULL;

        if (get_string (&t, &temp))
        {
            spec_destroy (&s);
            return 1;
        }
        eat_spaces (&t);

        if (*t == '-')
        {
            byte *temp2 = NULL;

            /* skip the '-' character */
            t++;
            eat_spaces (&t);

            if (get_string (&t, &temp2))
            {
                mem_free ((void **) (void *) &temp);
                spec_destroy (&s);
                return 1;
            }
            eat_spaces (&t);

            s->m_spec_type = st_byte_range;
            s->m_byte[0] = *temp;
            s->m_byte[1] = *temp2;

            mem_free ((void **) (void *) &temp2);
        }
        else
        {
            s->m_spec_type = st_byte;
            *s->m_byte = *temp;
        }

        mem_free ((void **) (void *) &temp);
    }
    else if (*t == '"')
    {
        if (get_string (&t, &s->m_string))
        {
            spec_destroy (&s);
            return 1;

⌨️ 快捷键说明

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