gpt4 book ai didi

c - 编译问题

转载 作者:太空宇宙 更新时间:2023-11-03 23:47:46 25 4
gpt4 key购买 nike

所以我必须为 Tiny C 语言创建一个编译器,但我无法编译它,我有 .y 和 .l 文件并且都可以正常工作,但是当我尝试编译 .tab.c 文件时,它显示 3 个错误

  • 对“install_id”的 undefined reference
  • 对 printSymtab 的 undefined reference
  • 对“lookup_id”的 undefined reference

代码如下:

符号表.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct symtab_node * SYMTAB;

typedef struct symtab_node {
char * nombre;
int type;
float fval;
SYMTAB next;
} SYMTAB_NODE;

SYMTAB lookup_id(SYMTAB st, char * name);

SYMTAB install_id(SYMTAB st, char * name, int typ);

void printSymtab(SYMTAB t);

符号表.c

#include "symtab.h"
#include <stdio.h>
int next_num() {
static int i = 1;
return i++;
}
/* looks up an is in ST. Returns pointer to cell if found else NULL */
SYMTAB lookup_id(SYMTAB st, char * name) {
SYMTAB tmp = st;
if (tmp == NULL) {/* empty list */
return NULL;
} else {
while (tmp != NULL) {
if (strcmp(tmp->idname,name) == 0) {
return tmp; /* found */
} else {
tmp = tmp->next; /* go to next cell */
}
}
return NULL; /* not found */
}
}
/* adds an id to ST if not present */
SYMTAB install_id(SYMTAB st, char * name, int typ) {
if (lookup_id(st, name) == NULL) {
SYMTAB nst = (SYMTAB)malloc(sizeof(SYMTAB_NODE));
nst->idname = (char *) strdup(name);
nst->idnum = next_num();
nst->next = st;
return nst;
} else {
return st;
}
}
/* print out ST */
void printSymtab(SYMTAB t) {
SYMTAB tmp = t;
while (tmp != NULL) {
printf("%s\t%d\n", tmp->idname, tmp->idnum);
tmp = tmp->next;
}
}

语法.y

    %{

#include "symtab.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char * concat (char * str1, char * str2);

extern int yylex();
extern char * yytext;
extern int yylineno;

SYMTAB st;

int typev;

/* Function definitions */

void yyerror (char *string);

%}

%union{
char *strval;
int value;
float fvalue;
SYMTAB st;
}

/* Declaramos todos los tokens que recibirá el programa y que provienen del cparser.l */
%token SEMI INTEGER FLOAT
%token IF THEN ELSE WHILE DO
%token READ WRITE
%token LPAREN RPAREN LBRACE RBRACE
%token LT EQ
%token PLUS MINUS TIMES DIV ASSIGN
%token<value> INT_NUM
%token<fvalue> FLOAT_NUM
%token<strval> ID

%%

/* Definimos las reglas de producción para el mini-lenguaje C */
program: var_dec stmt_seq { printf ("No hay errores sintacticos\n");}
;

var_dec: var_dec single_dec
|
;

single_dec: type ID SEMI { st = install_id(st,$2,typev); printSymtab(st); }
;

type: INTEGER { typev = 1; }
| FLOAT { typev = 2; }
;

stmt_seq: stmt_seq stmt
|
;

stmt: IF exp THEN else
| WHILE exp DO stmt
| variable ASSIGN exp SEMI { /*st = install_id(st,$1); */}
| READ LPAREN variable RPAREN SEMI { /*st = install_id(st,$3); */}
| WRITE LPAREN exp RPAREN SEMI
| block
| error SEMI { yyerrok;}
;

else: stmt
| ELSE stmt
;

block: LBRACE stmt_seq RBRACE
;

exp: simple_exp LT simple_exp
| simple_exp EQ simple_exp
| simple_exp
;

simple_exp: simple_exp PLUS term
| simple_exp MINUS term
| term
;

term: term TIMES factor
| term DIV factor
| factor
;

factor: LPAREN exp RPAREN
| INT_NUM
| FLOAT_NUM
| variable
;

variable: ID
{ if(lookup_id(st,$1) == NULL){
yyerror(concat("Error: Undeclared Identifier ", $1));
}
}
;
%%

/* A function that concatenates two strings and returns the result */
char * concat(char * str1, char * str2){
char *str3;
str3 = (char *) calloc(strlen(str1)+strlen(str2)+1, sizeof(char));
strcpy(str3,str1);
strcat(str3,str2);
return str3;
}

#include "lex.yy.c"

/* Bison does NOT implement yyerror, so define it here */
void yyerror (char *string){
printf ("ERROR NEAR LINE %d: %s\n",yylineno,string);
}

/* Bison does NOT define the main entry point so define it here */
main (){
yyparse();
yylex();
}

lexem.y

%{
#include <string.h>
#include <stdlib.h>

char * strval;
int value;
float fvalue;
int error;

extern YYSTYPE yylval;
%}

/* This is the rule definition */
%option noyywrap
%option yylineno

ids [A-Za-z_][A-Za-z0-9_]*
digits 0|[1-9][0-9]*|0(c|C)[0-7]+|0(x|X)[0-9A-Fa-f]+
floats [0-9]*"."[0-9]+([eE][-+]?[0-9]+)?

%%

/* Consume los comentarios*/
(\/\*([^\*]|\*[^/])*\*\/)|(\/\/.*)

/* Consume los espacios, tabulaciones y saltos de linea*/
[[:space:]]|[[:blank:]]|\n

/* Palabras reservadas */
"int" { return INTEGER; }
"float" { return FLOAT; }
"if" { return IF; }
"then" { return THEN; }
"else" { return ELSE; }
"do" { return DO; }
"while" { return WHILE; }
"read" { return READ; }
"write" { return WRITE; }

/* Simbolos de puntuacion, operadores y relacionales */
/* Puntuacion */
";" { return SEMI; }
"(" { return LPAREN; }
")" { return RPAREN; }
"{" { return LBRACE; }
"}" { return RBRACE; }

/* Relacionales */
">" { return LT; }
"==" { return EQ; }

/* Operadores */
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return TIMES; }
"/" { return DIV; }
"=" { return ASSIGN; }

{ids} { yylval.strval = (char *) strdup(yytext);
return (ID); }

{digits} { yylval.value = atoi(yytext);
return (INT_NUM); }

{floats} { yylval.fvalue = atof(yytext);
return (FLOAT_NUM); }

/* Consume los simbolos que sobran y marca error */
. { printf("LEXICAL ERROR NEAR LINE %d: %s \n", yyget_lineno(), yyget_text()); error++; }

%%

最佳答案

您不应该编译 whatever.tab.h 文件,它是一个 header 文件,其中包含语法的 YACC 元素,包含lexyacc 代码部分,以及您自己的代码(如果您需要访问它)。

你应该编译 whatever.tab.c,确保你还包括你的 symtab.c(或它的等效目标文件),以及任何其他 C 源文件也是如此。

而且,根据您的评论,正是这种不包含 symtab.c 文件的做法确实导致了您的直接错误。

当我执行您的步骤时(针对不同的名称略作修改):

flex lexem.l
yacc -d -v grammar.y
gcc -o par y.tab.c

然后我遇到了与您所看到的类似的问题:

/tmp/ccI5DpZQ.o:y.tab.c:(.text+0x35c): undefined reference to `install_id'
/tmp/ccI5DpZQ.o:y.tab.c:(.text+0x36e): undefined reference to `printSymtab'
/tmp/ccI5DpZQ.o:y.tab.c:(.text+0x3a7): undefined reference to `lookup_id'

但是,当我将 symtab.c 文件合并到编译行中时(并将 idnameidnum 缺失的位添加到结构中在 symtab.h 中解决编译问题),它工作得很好:

gcc -o par y.tab.c symtab.c

所以这就是您需要做的,在gcc 命令行中包含symtab.c

关于c - 编译问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28711388/

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