gpt4 book ai didi

c - 在以下 lex/yacc 文件中接收段错误(核心转储)。他们怎么了?

转载 作者:行者123 更新时间:2023-11-30 19:10:17 25 4
gpt4 key购买 nike

我遇到以下代码的段错误(核心转储):

lex文件如下,测试.l:

    %{

#include "y.tab.h"

#define LOOKUP 0

int state;

int add_word(int type, char *word);
int lookup_word(char *word);
%}

%%

\n {state = LOOKUP;}
\.\n {state = LOOKUP;
return 0;
}

^verb {state = VERB;}
^adj {state = ADJECTIVE;}
^adv {state = ADVERB;}
^noun {state = NOUN;}
^prep {state = PREPOSITION;}
^pron {state = PRONOUN;}
^conj {state = CONJUNCTION;}

[a-zA-Z]+ {
if(state != LOOKUP){
add_word(state, yytext);
}else{
switch(lookup_word(yytext)){
case VERB: return(VERB);
case ADJECTIVE: return(ADJECTIVE);
case ADVERB: return(ADVERB);
case NOUN: return(NOUN);
case PREPOSITION: return(PREPOSITION);
case PRONOUN: return(PRONOUN);
case CONJUNCTION: return(CONJUNCTION);
default:
printf("%s: don't recog\n",yytext);
}
}
}
. ;

%%
struct word{
char *word_name;
int word_type;
struct word *next;
};

struct word *word_list;

extern void *malloc();

int add_word(int type, char *word){
struct word *wp;
if(lookup_word(word) != LOOKUP){
printf("word %s already defined\n", word);
return 0;
}

wp = (struct word *) malloc(sizeof(struct word));

wp-> next = word_list;

wp-> word_name = (char*) malloc(strlen(word)+1);
strcpy(wp->word_name, word);
wp->word_type = type;
word_list = wp;
return 1;
}

int lookup_word(char *word){
struct word *wp = word_list;

for(; wp; wp = wp->next){
if(strcmp(wp->word_name, word) == 0)
return wp->word_type;
}
return LOOKUP;
}

yacc文件如下,

测试.y:

%{

#include <stdio.h>

%}

%token NOUN PRONOUN VERB ADVERB ADJECTIVE PREPOSITION CONJUNCTION

%%
sentence: subject VERB object {printf("sentence is valid\n");}
;

subject: NOUN
| PRONOUN
;
object: NOUN
;

%%

extern FILE *yyin;

main(){
while(!feof(yyin)){
yyparse();
}
}

yyerror(s)
{
fprintf(stderr, "some error\n");
}

我已经尝试了几个小时来找出问题所在。我对这些完全陌生,并且正在阅读“O'reilly - Lex 和 Yacc”一书。

最佳答案

由 (f)lex 生成的扫描器(负责执行输入的组件)将 yyinyyout 初始化为 stdinstdout,分别在其初始化函数期间。在此之前,由于 C 的静态初始化规则(即全局指针变量被初始化为 NULL),它们都是 NULL 指针。

第一次调用yylex时会调用初始化函数。 (它设置一个标志,以便下次调用 yylex 时不会再次进行初始化。这是初始化库系统的非常典型的方法;大多数 malloc 实现和一些实现C stdio 函数做同样的事情。)

yylexyyparse 重复调用,因此第一次调用 yyparse 会隐式初始化 yylex。但是当你写:

main(){ 
while(!feof(yyin)){
yyparse();
}
}

首次使用yyin发生在初始化之前。因此,第一次计算 while 条件时,yyin 仍为 NULL,因此不会有第二次;由此产生的段错误是致命的。

您可以通过自己初始化 yyin 来解决这个问题,但由于 while (!feof(file)) 总是错误的 (sm),将 EOF 测试放在循环的末尾会更有意义:

int main(){ 
do yyparse(); while (!feof(yyin));
}

参见this very helpful SO answer对于问题为什么“while (!feof (file))”总是错误?进行详 segmentation 析。

关于c - 在以下 lex/yacc 文件中接收段错误(核心转储)。他们怎么了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41640490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com