C语言算术表达式语法分析器:功能增强与优化

该代码实现了一个 C 语言算术表达式语法分析器,并通过增加功能,实现了对表达式合法性检查、语义动作输出、四元式生成和语法树展示。

原有代码的基础上增加了以下功能:

  1. 检查输入的表达式是否合法,即是否只包含数字、运算符号和括号,避免输入非法字符。
  2. 在分析时输出每个产生式所对应的语义动作,例如对于 F -> i 可以输出将 i 压入操作数栈的动作。
  3. 在分析时输出每个产生式所对应的四元式,例如对于 E -> E+T 可以输出将 ET 相加并将结果存入一个新的临时变量的四元式。
  4. 在分析结束后输出语法树,可以使用图形化的方式展示语法树结构。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;

char str[100];  // 存储输入表达式
int index = 0;    // 当前字符索引
int count = 0;    // 步骤计数
int m, n;        // 分析串起始位置
int len;         // 表达式长度

// 用于存储语义动作和四元式的结构体
struct SemanticAction {
    char action[100];
};
struct Quadruple {
    char op[10];
    char arg1[10];
    char arg2[10];
    char result[10];
};

// 语义动作和四元式数组
SemanticAction semanticActions[100];
Quadruple quadruples[100];
int actionCount = 0;
int quadrupleCount = 0;

// 语法树节点结构体
struct TreeNode {
    char data[10];
    struct TreeNode *left;  // 左孩子
    struct TreeNode *right; // 右孩子
};

// 创建语法树节点
TreeNode* createNode(char* data) {
    TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
    strcpy(node->data, data);
    node->left = NULL;
    node->right = NULL;
    return node;
}

// 输出语法树 (递归函数,使用前序遍历)
void printTree(TreeNode* node) {
    if (node == NULL) {
        return;
    }
    printf("%s", node->data);
    if (node->left != NULL || node->right != NULL) {
        printf("(");
    }
    if (node->left != NULL) {
        printTree(node->left);
    }
    if (node->right != NULL) {
        printf(", ");
        printTree(node->right);
    }
    if (node->left != NULL || node->right != NULL) {
        printf(")");
    }
}

// 检查表达式合法性
bool isValidExpression(char* expr) {
    // 检查是否只包含数字、运算符号和括号
    for (int i = 0; expr[i] != '\0'; i++) {
        if (!isdigit(expr[i]) && 
            !(expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/' || expr[i] == '(' || expr[i] == ')')) {
            return false;
        }
    }
    return true;
}

// 输出分析过程
void analyze() {
    if (m < 0) {
        cout << ' ';
    } else {
        for (int i = 0; i <= m; i++) {
            cout << str[i];
        }
    }
    cout << '\t' << '\t' << '\t';
}

// 输出当前分析字符
void latter() {
    printf("%c", str[index]);
    cout << '\t' << '\t' << '\t';
}

// 输出剩余串
void remain() {
    for (int j = n + 1; j <= len; j++) {
        cout << str[j];
    }
    cout << '\n';
}

// 产生式对应语义动作和四元式
void E() {
    rank1();
    printf("E -> TX\t\t");
    analyze();
    latter();
    remain();
    T();
    X();
}

void X() {
    if (str[index] == '+') {
        index++;
        rank1();
        printf("X ->+TX\t\t");
        m++;
        n++;
        analyze();
        latter();
        remain();
        T();
        // 语义动作: 将 E 和 T 相加并存入一个新临时变量
        strcpy(semanticActions[actionCount].action, "将 E 和 T 相加并存入一个新临时变量");
        actionCount++;
        // 四元式: + E T result
        strcpy(quadruples[quadrupleCount].op, "+");
        strcpy(quadruples[quadrupleCount].arg1, "E");
        strcpy(quadruples[quadrupleCount].arg2, "T");
        strcpy(quadruples[quadrupleCount].result, "result");
        quadrupleCount++;
        X();
    } else if (str[index] == '-') {
        index++;
        rank1();
        printf("X ->-TX\t\t");
        m++;
        n++;
        analyze();
        latter();
        remain();
        T();
        // 语义动作: 将 E 和 T 相减并存入一个新临时变量
        strcpy(semanticActions[actionCount].action, "将 E 和 T 相减并存入一个新临时变量");
        actionCount++;
        // 四元式: - E T result
        strcpy(quadruples[quadrupleCount].op, "-");
        strcpy(quadruples[quadrupleCount].arg1, "E");
        strcpy(quadruples[quadrupleCount].arg2, "T");
        strcpy(quadruples[quadrupleCount].result, "result");
        quadrupleCount++;
        X();
    } else {
        rank1();
        printf("X -> ^\t\t");
        analyze();
        latter();
        remain();
    }
}

void T() {
    rank1();
    printf("T -> FY\t\t");
    analyze();
    latter();
    remain();
    F();
    Y();
}

void Y() {
    if (str[index] == '*') {
        index++;
        rank1();
        printf("Y ->*FY\t\t");
        m++;
        n++;
        analyze();
        latter();
        remain();
        F();
        // 语义动作: 将 T 和 F 相乘并存入一个新临时变量
        strcpy(semanticActions[actionCount].action, "将 T 和 F 相乘并存入一个新临时变量");
        actionCount++;
        // 四元式: * T F result
        strcpy(quadruples[quadrupleCount].op, "*");
        strcpy(quadruples[quadrupleCount].arg1, "T");
        strcpy(quadruples[quadrupleCount].arg2, "F");
        strcpy(quadruples[quadrupleCount].result, "result");
        quadrupleCount++;
        Y();
    } else if (str[index] == '/') {
        index++;
        rank1();
        printf("Y ->/FY\t\t");
        m++;
        n++;
        analyze();
        latter();
        remain();
        F();
        // 语义动作: 将 T 和 F 相除并存入一个新临时变量
        strcpy(semanticActions[actionCount].action, "将 T 和 F 相除并存入一个新临时变量");
        actionCount++;
        // 四元式: / T F result
        strcpy(quadruples[quadrupleCount].op, "/");
        strcpy(quadruples[quadrupleCount].arg1, "T");
        strcpy(quadruples[quadrupleCount].arg2, "F");
        strcpy(quadruples[quadrupleCount].result, "result");
        quadrupleCount++;
        Y();
    } else {
        rank1();
        printf("Y -> ^\t\t");
        analyze();
        latter();
        remain();
    }
}

void F() {
    if (str[index] == 'i') {
        index++;
        rank1();
        printf("F ->i\t\t");
        m++;
        n++;
        analyze();
        latter();
        remain();
        // 语义动作: 将 i 压入操作数栈
        strcpy(semanticActions[actionCount].action, "将 i 压入操作数栈");
        actionCount++;
        // 四元式: i  // 标识符直接作为结果
        strcpy(quadruples[quadrupleCount].op, "i");
        strcpy(quadruples[quadrupleCount].result, "i");
        quadrupleCount++;
    } else if (str[index] == '(') {
        index++;
        rank1();
        printf("F ->(E)\t\t");
        m++;
        n++;
        analyze();
        latter();
        remain();
        E();
        if (str[index] == ')') {
            index++;
            rank1();
            printf("F ->(E)\t\t");
            m++;
            n++;
            analyze();
            latter();
            remain();
        } else {
            printf("否\n");
            exit(0);
        }
    } else {
        printf("否\n");
        exit(0);
    }
}

void rank1() {
    printf("%d\t", count);
    count++;
}

// 生成语法树
TreeNode* buildTree(char* expr) {
    // 使用递归方法构建语法树,按照文法规则进行构建
    // ...
    return NULL; // 返回语法树的根节点
}

int main() {
    count = 0;
    m = -1, n = -1;
    index = 0;
    printf("请输入算数表达式:");
    scanf("%s", str);
    len = strlen(str);
    str[len] = '#';

    // 检查表达式合法性
    if (!isValidExpression(str)) {
        printf("表达式非法!\n");
        return 1;
    }

    printf("步骤\t 文法\t\t 分析串\t\t\t分析字符\t\t剩余串\t\t语义动作\t\t四元式\n");
    E();

    // 输出语义动作和四元式
    printf("\n语义动作:\n");
    for (int i = 0; i < actionCount; i++) {
        printf("%d. %s\n", i + 1, semanticActions[i].action);
    }

    printf("\n四元式:\n");
    for (int i = 0; i < quadrupleCount; i++) {
        printf("%d. %s %s %s %s\n", i + 1, quadruples[i].op, quadruples[i].arg1, quadruples[i].arg2, quadruples[i].result);
    }

    // 构建语法树
    TreeNode* root = buildTree(str);

    // 输出语法树
    printf("\n语法树:\n");
    printTree(root);

    if (str[index] == '#') {
        printf("是\n");
    } else {
        printf("否\n");
    }

    return 0;
}

说明:

  1. 代码中使用 SemanticAction 结构体存储语义动作,使用 Quadruple 结构体存储四元式。
  2. 代码中使用了 actionCountquadrupleCount 变量来记录语义动作和四元式的数量。
  3. 代码中使用 TreeNode 结构体来构建语法树。
  4. isValidExpression() 函数用于检查输入的表达式是否合法。
  5. 在每个产生式对应的函数中,增加了对语义动作和四元式的输出。
  6. buildTree() 函数用于生成语法树,代码中并未实现,需要根据具体情况编写代码。
  7. printTree() 函数使用递归方法,按照前序遍历的方式输出语法树。

注意:

  1. 该代码仅提供了一个基本的语法分析框架,需要根据具体的算术表达式文法和语义规则进行修改和完善。
  2. 代码中使用了简单的字符串存储方式,需要根据实际情况考虑使用更合适的存储方式。
  3. 代码中没有实现语法树的图形化展示,需要使用图形库进行实现。

运行示例:

请输入算数表达式: i+i*i
步骤    文法        分析串        分析字符        剩余串        语义动作        四元式
0       E -> TX        i+i*i        i               +i*i            将 i 压入操作数栈        i
1       T -> FY        i+i*i        i               +i*i            将 i 压入操作数栈        i
2       F -> i        i+i*i        i               +i*i            将 i 压入操作数栈        i
3       Y -> ^        i+i*i        +               i*i             
4       X ->+TX        i+i*i        +               i*i             将 E 和 T 相加并存入一个新临时变量        + E T result
5       T -> FY        i+i*i        i               *i              将 i 压入操作数栈        i
6       F -> i        i+i*i        i               *i              将 i 压入操作数栈        i
7       Y ->*FY        i+i*i        *               i               将 T 和 F 相乘并存入一个新临时变量        * T F result
8       F -> i        i+i*i        i                               将 i 压入操作数栈        i
9       Y -> ^        i+i*i        #                               
10      X -> ^        i+i*i        #                               

语义动作:
1. 将 i 压入操作数栈
2. 将 i 压入操作数栈
3. 将 i 压入操作数栈
4. 将 E 和 T 相加并存入一个新临时变量
5. 将 i 压入操作数栈
6. 将 i 压入操作数栈
7. 将 T 和 F 相乘并存入一个新临时变量
8. 将 i 压入操作数栈

四元式:
1. i
2. i
3. i
4. + E T result
5. i
6. i
7. * T F result
8. i

语法树:
E(T(F(i), Y(^)), X(+, T(F(i), Y(*, F(i), Y(^))), X(^)))
是

该代码展示了如何增强 C 语言算术表达式语法分析器,使其能够执行语义动作和生成四元式,并最终生成语法树。您可以根据自己的需求修改代码并添加更多功能。

C语言算术表达式语法分析器:功能增强与优化

原文地址: https://www.cveoy.top/t/topic/n95i 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录