| 网站首页 | 业界新闻 | 群组 | 交易 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
乐学 会学 多求 善思千里之行 始于足下
共有 135 人关注过本帖
标题:GDB调试可以运行,正常运行出现段错误,如何解决?
只看楼主 加入收藏
rrc88
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2019-1-20
结帖率:50%
  已结贴   问题点数:20  回复次数:1   
GDB调试可以运行,正常运行出现段错误,如何解决?
程序代码:
/**
 * 在这部分中,你将使用图转移算法手工实现一个小型的词法分析器。
 * 分析器的输入:存储在文本文件中的字符序列,字符取自ASCII字符集。文件中可能包括四种记号:关键字if、符合C语言标准的标识符、空格符、回车符\n。
 * 分析器的输出:打印出所识别的标识符的种类、及行号、列号信息。
 【示例】对于下面的文本文件:
  ifx if iif       if
  iff    if
 你的输出应该是:
 ID(ifx) (1, 1)
 IF        (1, 4)
 ID(iif)  (1, 8)
 IF       (1, 13)
 ID(iff) (2, 1)
 IF       (2, 8)
*/

#include <stdio.h>

enum        kind {IF, ID};
static int  program_pos = 0;              // 当前词法分析器读取文件位置
static int  program_col = 0;              // 记录文件列数
static int  program_line = 0;             // 记录文件行数
int         program_len = 0;              // 记录文件总长度
char        program[1000];                // 存放文件内容的数组
char        lexeme[10];                   // 存放词素
int         lexeme_len = 0;               // 存放词素长度

void compile();
void s0(char c);
void s1(char c);
void s2(enum kind k);
void s3(char c);
void s4(char c);
int  handle_skip_character(char c);        // 处理'\n','\t', ' '字符
void rollback();
void print_lexeme(enum kind k);
void compile_error();

int main() {
    printf("110");
    FILE *fp = fopen("program", "r");
    if (fp == NULL) {
        printf("file can't open");
        return 0;
    }
   
    for (;; ++program_len) {
        fscanf(fp, "%c", &program[program_len]);
        if (program[program_len] == EOF)
            break;
    }
    printf("%s", program);
    fclose(fp);

    compile();

    return 0;
}


void compile()
{
    for (; program_pos < program_len; program_pos ++)
            s0(program[program_pos]);
}

void s0(char c)
{
    if (handle_skip_character(c))
        return;
    lexeme[lexeme_len ++] = c;
    if ( (c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z') || c == '_' ) {
        lexeme[lexeme_len ++] = c;
        if (c == 'i')
            s3(program[program_pos ++]);
        else
            s1(program[program_pos ++]);
    }
}

void s1(char c)
{
    if (handle_skip_character(c)) {
        s2(ID);
        return;
    }
    lexeme[lexeme_len ++] = c;
    char nextc = program[program_pos ++];
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
        (c >= '0' && c <= '9') || c == '_')
        s1(nextc);
    else
        s2(ID);
}

void s2(enum kind k)
{
    lexeme_len = 0;  // 惰性删除词素
    rollback();
    print_lexeme(k);
}

void s3(char c)
{
    lexeme[lexeme_len ++] = c;
    char nextc = program[program_pos ++];
    if (c == 'f')
        s4(nextc);
    else
        s1(nextc);
}

void s4(char c)
{
    lexeme[lexeme_len ++] = c;
    char nextc = program[program_pos ++];
    if (handle_skip_character(c))
        s2(IF);
    else
        s1(nextc);
}

void print_lexeme(enum kind k) {
    if (k == ID) {
        for (int i = 0; i < lexeme_len; i ++)
            printf("ID(%c)\t\t(%d, %d)",
                program[program_pos], program_line, program_col);
    }
    else if (k == IF) {
        printf("IF\t\t\t(%d,%d)",
            program_line, program_col);
    }
}

int handle_skip_character(char c) {
    if (program[program_pos] == EOF)
        return 1;
    else if (program[program_pos] == '\n') {
        program_col = 0;
        program_line ++;
        return 1;
    }
    else if (program[program_pos] == '\t') {
        program_col += 4;
        return 1;
    }
    else if (program[program_pos] == ' ') {
        program_col ++;
        return 1;
    }
    return 0;
}

void compile_error()
{
    printf("Invalid lexeme");
}

// program_pos回退函数
void rollback()
{
    if (program_pos > 0)
        --program_pos;
}

 
 
终端使用GCC编译出现段错误,但是用GDB运行可以出现结果,怎么解决?

[此贴子已经被作者于2019-1-24 20:58编辑过]

2019-01-24 19:59
ZJYTY
Rank: 4
等 级:业余侠客
威 望:1
帖 子:41
专家分:265
注 册:2018-12-20
  得分:20 
仅做分析:下面几个函数里可能会出现char lexeme[10]越界

程序代码:
int main() {
    printf("110");
    FILE *fp = fopen("../program.txt", "r");
    if (fp == NULL) {
        printf("file can't open");
        return 0;
    }

    for (;; ++program_len) {
        fscanf(fp, "%c", &program[program_len]);
        if (program[program_len] == EOF)
            break;
    }
    printf("%s", program);
    fclose(fp);

    compile();

    getchar();
    return 0;
}


void compile()
{
    for (; program_pos < program_len; program_pos++)
        s0(program[program_pos]);
}

void s0(char c)
{
    if (handle_skip_character(c))
        return;
    lexeme[lexeme_len++] = c;
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
        lexeme[lexeme_len++] = c;
        if (c == 'i')
            s3(program[program_pos++]);
        else
            s1(program[program_pos++]);
    }
}

-------------------------------若有不当之处,敬请谅解-------------------------------
2019-01-25 09:34







关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.050362 second(s), 9 queries.
Copyright©2004-2019, BCCN.NET, All Rights Reserved