Exemplo n.º 1
0
        get_production(short conflict_number,
                       DslToken tokens)
        {
            short entry = 0;
            int   index, level;

            if (conflict_number <= TOTAL_CONFLICTS)
            {
                entry = (short)(conflict_number + (START_CONFLICT - 1));
                level = 1;
                while (entry >= START_CONFLICT)
                {
                    index  = Conflict_row [entry - (START_CONFLICT - 1)];
                    index += tokens.peek(level);
                    entry  = Conflict [index];
                    ++level;
                }
            }

            return(entry);
        }
Exemplo n.º 2
0
        parse(ref DslAction action,
              ref DslToken tokens,
              ref DslError error,
              short start_symbol)
        {
            short rhs, lhs;
            short production_number, entry, symbol, token, new_token;
            int   production_length, top, index, level;

            short *stack = stackalloc short[65535];

            top        = 65534;
            stack[top] = 0;
            if (start_symbol == 0)
            {
                start_symbol = START_SYMBOL;
            }
            if (top > 0)
            {
                stack[--top] = start_symbol;
            }
            else
            {
                error.message("DslParse: stack overflow\n", ref tokens); return;
            }
            token     = tokens.get();
            new_token = token;

            for (symbol = (stack[top] != 0 ? stack[top++] : (short)0); symbol != 0;)
            {
                if (symbol >= START_ACTION)
                {
                    action.execute(symbol - (START_ACTION - 1));
                }
                else if (symbol >= START_SYMBOL)
                {
                    entry             = 0;
                    level             = 1;
                    production_number = get_conditional_production(symbol);
                    if (production_number != 0)
                    {
                        entry = get_predicted_entry(tokens,
                                                    production_number, token,
                                                    level, 1);
                    }
                    if (entry == 0)
                    {
                        index  = Parse_row[symbol - (START_SYMBOL - 1)];
                        index += token;
                        entry  = Parse[index];
                    }
                    while (entry >= START_CONFLICT)
                    {
                        index  = Conflict_row[entry - (START_CONFLICT - 1)];
                        index += tokens.peek(level);
                        entry  = Conflict[index];
                        ++level;
                    }
                    if (entry != 0)
                    {
                        index             = Production_row[entry];
                        production_length = Production[index] - 1;
                        lhs = Production[++index];
                        if (lhs == symbol)
                        {
                            action.predict(entry);
                            index += production_length;
                            for (; production_length-- > 0; --index)
                            {
                                if (top > 0)
                                {
                                    stack[--top] = Production[index];
                                }
                                else
                                {
                                    error.message("DslParse: stack overflow\n", ref tokens); return;
                                }
                            }
                        }
                        else
                        {
                            new_token = error.no_entry(symbol, token, level - 1, ref tokens);
                        }
                    }
                    else                                           // no table entry
                    {
                        new_token = error.no_entry(symbol, token, level - 1, ref tokens);
                    }
                }
                else if (symbol > 0)
                {
                    if (symbol == token)
                    {
                        token     = tokens.get();
                        new_token = token;
                    }
                    else
                    {
                        new_token = error.mismatch(symbol, token, ref tokens);
                    }
                }
                else
                {
                    error.message("\n parser error: symbol value 0\n", ref tokens);
                }
                if (token != new_token)
                {
                    if (new_token != 0)
                    {
                        token = new_token;
                    }
                    if (token != END_OF_SLK_INPUT_)
                    {
                        continue;
                    }
                }
                symbol = (stack[top] != 0 ? stack[top++] : (short)0);
            }
            if (token != END_OF_SLK_INPUT_)
            {
                error.input_left(ref tokens);
            }
        }