编译器设计LR解析器

问题描述 投票:0回答:1

编写一个编译器来确定以下输入字符串是否满足给定的 CFG (1) "(i+i)i$" (2) "(i)$" 我的项目构建但抛出异常

Cpsc323Handout8.exe 中的 0x00007FF883BDCF19 处抛出异常:Microsoft C++ 异常:内存位置 0x0000004B15CFECD0 处的 std::bad_alloc

#include <iostream>
#include <array>
#include <string>
#include <stack>

using namespace std;

string table[16][11] =
{ {"S5", "blank", "blank", "blank", "blank", "S4", "blank", "blank", "1", "2", "3"},
    {"blank", "S6", "S7", "blank", "blank", "blank", "blank", "ACC", "blank", "blank", "blank"},
    {"blank", "R3", "R3", "S8", "S9", "blank", "R3", "R3", "blank", "blank", "blank"},
    {"blank", "R6", "R6", "R6", "R6", "blank", "R8", "R8", "blank", "blank", "blank"},
    {"S5", "blank", "blank", "blank", "blank", "S4", "blank", "blank", "10", "2", "3"},
    {"blank", "R8", "R8", "R8", "R8", "blank", "R8", "R8", "blank", "blank", "blank"},
    {"S5", "blank", "blank", "blank", "blank", "S4", "blank", "blank", "blank", "11", "3"},
    {"S5", "blank", "blank", "blank", "blank", "S4", "blank", "blank", "blank", "12", "3"},
    {"S5", "blank", "blank", "blank", "blank", "S4", "blank", "blank", "blank", "blank", "13"},
    {"S5", "blank", "blank", "blank", "blank", "S4", "blank", "blank", "blank", "blank", "14"},
    {"blank", "S6", "S7", "blank", "blank", "blank", "S15", "blank", "blank", "blank", "blank"},
    {"blank", "R1", "R1", "S8", "S9", "blank", "R1", "R1", "blank", "blank", "blank"},
    {"blank", "R2", "R2", "S8", "S9", "blank", "R2", "R2", "blank", "blank", "blank"},
    {"blank", "R4", "R4", "R4", "R4", "blank", "R4", "R4", "blank", "blank", "blank"},
    {"blank", "R5", "R5", "R5", "R5", "blank", "R5", "R5", "blank", "blank", "blank"},
    {"blank", "R7", "R7", "R7", "R7", "blank", "R7", "R7", "blank", "blank", "blank"}
};

void printStack(stack<char> charStack)
{
    stack<char> temp;
    char character;

    while (charStack.empty() == false)
    {
        character = charStack.top();
        charStack.pop();
        temp.push(character);
    }
    cout << "stack: " << endl;
    while (temp.empty() == false)
    {
        cout << temp.top() << endl;
        temp.pop();
    }
}

int main()
{
    cout << "LR parsing table!" << endl;
    cout << "enter input with '$' at the end.\n input: ";

    /*  "(i+i)*i$" "(i*)$"  */

    string input;
    cin >> input;
    int current = 0;

    // Push input onto the stack
    stack<char> charStack;
    charStack.push('0');

    while (true)
    {
        char value = input[current];
        int valueNum;
        if (value == 'i')
        {
            valueNum = 0;
        }
        if (value == '+')
        {
            valueNum = 1;
        }
        if (value == '-')
        {
            valueNum = 2;
        }
        if (value == '*')
        {
            valueNum = 3;
        }
        if (value == '/')
        {
            valueNum = 4;
        }
        if (value == '(')
        {
            valueNum = 5;
        }
        if (value == ')')
        {
            valueNum = 6;
        }
        if (value == '$')
        {
            valueNum = 7;
        }
        if (value == 'E')
        {
            valueNum = 8;
        }
        if (value == 'T')
        {
            valueNum = 9;
        }
        if (value == 'F')
        {
            valueNum = 10;
        }

        string tableVal = table[charStack.top()][valueNum];
        if (tableVal[0] == 's')
        {
            charStack.push(value);
            current += 1;
            charStack.push(tableVal[0]);
            // Print the stack
            cout << "stack: ";
            printStack(charStack);
        }

        
            /*
            charStack.pop();
            // pop() the stack | x | 

            // switch abd push reduction
            // charStack.push(tableVal[1]);
            */
        else if (tableVal[0] == 'r')
        {
            // Determine which rule is being used for reduction
            int ruleNum = tableVal[1] - '0'; // Convert the rule number character to integer

            // Define the resulting non-terminal symbol and the length of the right-hand side
            char nonTerminal;
            int rhsLength;

            // Determine the resulting non-terminal symbol and the length of the right-hand side
            switch (ruleNum) {
            case 1: // E -> E + T
                nonTerminal = 'E';
                rhsLength = 3;
                break;
            case 2: // E -> E - T
                nonTerminal = 'E';
                rhsLength = 3;
                break;
            case 3: // E -> T
                nonTerminal = 'E';
                rhsLength = 1;
                break;
            case 4: // T -> T * F
                nonTerminal = 'T';
                rhsLength = 3;
                break;
                // Add cases for other rules similarly
            default:
                cout << "Unknown reduction rule: " << ruleNum << endl;
                return false;
            }

            // Pop symbols from the stack based on the length of the right-hand side of the rule
            for (int i = 0; i < rhsLength * 2; ++i) {
                charStack.pop();
            }

            // Push the resulting non-terminal symbol onto the stack
            charStack.push(nonTerminal);
        }
        else if (isdigit(tableVal[0]))
        {
            // charStack.push(tableVal);
        }
        else if (tableVal == "acc") {
            cout << "input completed ";
            break;

        }
        else {
            cout << "ERROR no table entry";
            break;
        }       
    }
    // Print the stack
    cout << "stack: ";
    printStack(charStack);

    return 0;
}


我希望我的程序能像这样输出 ( 我 + 我 ) * 我 输入完成

c++ compiler-construction
1个回答
0
投票

出现错误是因为这里

string tableVal = table[charStack.top()][valueNum];

charStack.top() 返回 48,大于表数组的大小。

charStack.push('0');

这里将字符“0”推入 charStack 数组。然后字符 0 由 charStack.top() 返回并隐式转换为整数 48,因为 48 是字符 '0' 的 ASCII 值

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.