【编译原理】符号表的实现C语言

编译原理符号表的实现C语⾔
最近在学习编译原理这门课。实验课⽼师让我们完成简易的符号表。内容是读出源程序中的标识符,并在符号表中进⾏查,若存在则输出该标识符及其编号和位置。否则将其填⼊符号表,并分配编号,确定位置,输出标识符表。
这个符号表的实现只让我们完成标识符的查和存储即可。刚开始我想使⽤顺序表,但是因为存储空间的局限性。最后选择了单链表。肯定会有更好的存储结构,但是我只会单链表。还有⼀些系统标识符没有写全,可⾃⾏添加。
直接上代码
//编译原理符号表,使⽤单链表
# include<stdlib.h>
#include <stdio.h>
#include<string.h>
#include <malloc.h>
# define PATH "D:\\编译原理代码\\编译原理\\符号表\\符号表.cpp"
typedef struct LNode {
char data[30];
LNode* next;
int location;
}LNode, *LinkList;
LinkList Init() {
LinkList L;
L = (LNode*)malloc(sizeof(LNode));
L->next = NULL;
L->location = 0;
return L;
}
//尾插
void InsertTail(LinkList L, char data[]) {
LNode* first = L;
while (L->next != NULL) {
L = L->next;
}//到最后⼀个
L->next = (LNode*)malloc(sizeof(LNode));
if (!L) return;
L->next->location = L->location + 1;
L = L->next;
int i = 0;
while (data[i] != '\0') {
L->data[i] = data[i];
i++;
}
L->data[i] = '\0';
3c技术L->next = NULL;
L = first;
}
//打印单链表
void print(LinkList LL) {
int i = 0;
LNode* first = LL;
while (LL->next != NULL) {
printf("位置%d ", LL->location);
LL = LL->next;
while (LL->data[i] != '\0') {
printf("%c", LL->data[i]);
i++;
}
i = 0;
printf("\n");
}
}
LL = first;
}
//判断表⾥是否已经有了该元素
//返回⼏表⽰在第⼏个,返回-1表⽰不存在
int hasElem(LinkList L, char data[]) {
bool flag = false;
int i = 0;
LNode* first;
first = L;
while (L->next != NULL) {
while (data[i] != '\0' && L->next->data[i] != '\0') {
if (data[i] == L->next->data[i]) {
i++;
if (data[i] == '\0' && L->next->data[i] == '\0') {
return L->next->location;
}
}
else {
break;
}
}
L = L->next;
i = 0;
}
L = first;
return -1;//表⽰没有相同元素
}
//test method
void printHasElem(LinkList L, char data[]) {
printf(hasElem(L, data) == -1 ? "符号表中没有该标识符" : "该标识符已位于符号表的第%d位", hasElem(L, data)); }
//是否是系统关键字,1表⽰是,-1表⽰不是
int isExist(char string[]) {站用变压器
char exist[40][10] = { {"char"},{"double"},{"enum"},{"float"},{"int"},{"long"} ,{"short"} ,{"signed"} ,
{"struct"} ,{"union"} ,{"unsigned"} ,{"void"} ,{"for"} ,{"do"} ,{"while"},{"break"},{"continue"},
{"if"},{"else"},{"goto"},{"switch"},{"case"},{"default"},{"return"},{"auto"},{"extern"},{"register"},{"static"},
{"const"},{"sizeof"},{"typedef"},{"volatile"},{"main"},{"printf"},{"include"},{"true"},{"bool"},{"false"} };
bool continue_ = false;
for (int i = 0; i < 35; i++) {
for (int j = 0; j < 35; j++) {
if (string[j] == exist[i][j]) {
continue_ = true;
}
else {
continue_ = false;
break;
}
if (string[j] == '\0' && exist[i][j] == '\0' && continue_ == true) {
return 1;//与关键字重复
贝勒斯>卢荣友}
}
}
return -1;
}
int isLegal(char string[]) {
bool flag = false;//是否是合法标识符
int i = 0;
if (string[0] <= '9' && string[0] >= '0')
return -1;
while (string[i] != '\0') {
if (string[i] == '_' || (string[i] >= 'a' && string[i] <= 'z' ||
(string[i] >= 'A' && string[i] <= 'Z')||
(string[i] >= '0' && string[i] <= '9'))){
(string[i] >= '0' && string[i] <= '9'))){
i++;
if (string[i] == '\0') {
flag = true;
break;
}
}
else {秦淮名妓
break;
}
}
if (flag) return 1;
return -1;
}
int printFile() {//打印⽂件内容的⽅法
//strtok内部有⼀个指针,如果第⼀个参数是空,则指针会指向上⼀次读取完的位置 int i = 0;
char word[100];
char buf[100];  /*缓冲区*/
FILE* fp;            /*⽂件指针*/
int len;            /*⾏字符个数*/
if ((fopen_s(&fp, PATH, "r")) != 0)//打开成功返回0 失败返回⾮0
return -1;
while (fgets(buf, 100, fp) != NULL) {
/
/printf("%s", buf);
char* ptr;
char* p = strtok_s(buf, " ;(,)=\n\t\0", &ptr);//p是⼀个指针,指到读取位置
while (p != NULL ) {
/*while (*(++p) != '\0') {
(p--);
word[i] = *p;
}
i = 0;
printf("%d", isLegal(word));*/
/*char* ptrr;
char* pp = strtok_s(p, " ", &ptrr); {
while (pp != NULL) {
printf("%s\n", p);
p = strtok_s(NULL, " ", &ptrr);
}
}*/
printf("%s\n",p);
//printf("%d\n", isLegal(p));
p = strtok_s(NULL, " ;(,)=\n\t\0", &ptr);//
}
}
return 0;
}
int lastFunction(LinkList L) {
int i = 0;
char word[100];
char buf[100];  /*缓冲区*/审核员
FILE* fp;            /*⽂件指针*/
if ((fopen_s(&fp, PATH, "r")) != 0)//打开成功返回0 失败返回⾮0
return -1;
while (fgets(buf, 100, fp) != NULL) {
char* ptr;
/
/strtok第⼆个参数表⽰以..分割,可多个杂糅在⼀起
char* p = strtok_s(buf, " *;(,)=\n\t\0", &ptr);//p是⼀个指针,指到读取位置
while (p != NULL) {
while (*p != '\0') {
word[i++] = *p++;
}
}
word[i] = '\0';
//printf("%s\n", word);
if (isExist(word) == -1) {//系统不存在该关键字
if (isLegal(word) == 1) {//p合法
if (hasElem(L, word) == -1) {//表⽰L表中没有该元素
//printf("%s\n", word);
InsertTail(L, word);
}
else {
printf("表中已存在%s元素,在第%d个\n", word, hasElem(L, word));    }
}
}
i = 0;
p = strtok_s(NULL, " *;(,)=\n\t\0", &ptr);//
}
}
}
int main() {
LinkList L;
L = Init();
LNode* first = L;
lastFunction(L);
printf("----------------\n");
print(L);
return 0;
}

本文发布于:2024-09-21 22:45:25,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/476318.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:符号表   标识符   原理   返回   编译   位置
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议