예제 #1
0
 internal short no_entry(short nonterminal, short token, int level, ref DslToken dslToken)
 {
     mHasError = true;
     mLog.Log("[error] syntax error: skipping input {0}, last token {1} line {2}, cur token {3} line {4}", DslString.GetSymbolName(token), dslToken.getLastToken(), dslToken.getLastLineNumber(), dslToken.getCurToken(), dslToken.getLineNumber());
     token = dslToken.get(); // advance the input
     return(token);
 }
예제 #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);
            }
        }