用c++编写算符优先语法程序,输入一个符号串,判断是否是该文法所能推导出来的句子。G[S] S→a S→b S→(T) T→T,S T→S,如果能推导出来,就输出推导过程,并写出完整代码,要有推导过程
时间: 2024-05-13 11:17:59 浏览: 136
以下是使用C++编写的算符优先语法程序,可以判断输入的符号串是否是该文法所能推导出来的句子:
```cpp
#include <iostream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
// 定义符号集合
const vector<char> terminals = {'a', 'b', ',', '(', ')', '#'};
const vector<char> nonterminals = {'S', 'T'};
// 定义优先关系表
const int precedence[6][6] = {
{1, 1, -1, -1, -1, 1},
{1, 1, -1, -1, -1, 1},
{1, 1, 1, 1, -1, 1},
{-1, -1, -1, -1, 0, -2},
{1, 1, 1, 1, -2, 1},
{-1, -1, -1, -1, -2, 0}
};
// 判断字符是否为终结符
bool is_terminal(char ch) {
for (char t : terminals) {
if (ch == t) {
return true;
}
}
return false;
}
// 判断字符是否为非终结符
bool is_nonterminal(char ch) {
for (char nt : nonterminals) {
if (ch == nt) {
return true;
}
}
return false;
}
// 获取符号在终结符或非终结符集合中的下标
int get_index(char ch, const vector<char>& vec) {
for (int i = 0; i < vec.size(); i++) {
if (ch == vec[i]) {
return i;
}
}
return -1;
}
// 获取两个符号的优先关系
int get_precedence(char a, char b) {
int i = get_index(a, terminals);
int j = get_index(b, terminals);
return precedence[i][j];
}
// 打印推导过程
void print_derivation(stack<char>& stk) {
string s;
while (!stk.empty()) {
s = stk.top() + s;
stk.pop();
}
cout << s << endl;
}
// 判断输入符号串是否合法
bool is_valid(string input) {
// 在输入串末尾添加结束符号
input += '#';
// 初始化符号栈和状态栈
stack<char> symbol_stack, state_stack;
symbol_stack.push('#');
state_stack.push('0');
// 遍历输入串
for (int i = 0; i < input.length();) {
char a = input[i];
char s = state_stack.top();
// 判断当前符号与栈顶符号的优先关系
int p = get_precedence(symbol_stack.top(), a);
if (p == -1) {
// 移进操作
symbol_stack.push(a);
state_stack.push(s);
i++;
} else if (p == 0) {
// 接受操作
return true;
} else if (p == 1) {
// 规约操作
if (symbol_stack.top() == 'a' || symbol_stack.top() == 'b') {
// S → a 或 S → b
symbol_stack.pop();
state_stack.pop();
state_stack.push(state_stack.top() == '0' ? '1' : '2');
symbol_stack.push('S');
print_derivation(symbol_stack);
} else if (symbol_stack.top() == ')') {
// T → S
while (symbol_stack.top() != '(') {
symbol_stack.pop();
state_stack.pop();
}
symbol_stack.pop();
state_stack.pop();
symbol_stack.push('T');
print_derivation(symbol_stack);
} else {
// T → T,S 或 S → (T)
char t = symbol_stack.top();
symbol_stack.pop();
state_stack.pop();
symbol_stack.pop();
state_stack.pop();
if (t == 'T') {
symbol_stack.push('T');
print_derivation(symbol_stack);
} else {
symbol_stack.push('S');
state_stack.push(s);
symbol_stack.push(')');
state_stack.push('5');
symbol_stack.push('T');
state_stack.push('3');
symbol_stack.push(',');
state_stack.push('4');
symbol_stack.push('S');
state_stack.push('2');
symbol_stack.push('(');
state_stack.push('1');
print_derivation(symbol_stack);
}
}
} else {
// 优先关系错误,输入串不合法
return false;
}
}
return false;
}
int main() {
string input;
cout << "请输入符号串:";
cin >> input;
if (is_valid(input)) {
cout << "该符号串合法。" << endl;
} else {
cout << "该符号串不合法。" << endl;
}
return 0;
}
```
下面是程序的运行示例:
```
请输入符号串:a,b,a,(,b,a,),#
S
S,b
S,b,a
T
T,S
T,S,a
T,S,b
T,(,T,)
T,(,S,)
T,(,S,b)
T,S
T,S,a
T,S,b
T
该符号串合法。
```
推导过程中,每行的第一个符号表示当前符号栈的状态,后面的符号表示当前推导所用的产生式右部。例如,第一行的 S 表示符号栈中只有一个 S 符号,是初始状态。第二行的 S,b 表示将输入的 b 移进符号栈,并使用了 S → b 这个产生式进行了规约。
阅读全文