?? bylr.c
字號:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <malloc.h>
#include "stack.h"
struct symbolRecord
{
char symbol[10];
int id;
}record[15];
//讀入屬性
struct entryType
{
char idName[16];
int address;
char *type;
int value;
struct entryType* next;
};
//數表
struct digitTable
{
int address;
int digit;
struct digitTable *next;
};
//token字
struct tokenType
{
int id;
int entry;
struct tokenType* next;
};
//語法分析產生語法分析樹
struct creat
{
int id;
int length;
char left;
char string[32];
}grammar[20];
//非終結符
struct term
{
int id;
char character;
}nonTerminate[10];
//四元式
struct equal
{
int id;
char first[16];
char second[16];
char third[16];
char forth[16];
}equalExp[32];
int entry=0, digit=0, instruction=0;
int line=0, row=0, cursor=-1;
char stringBuffer[128];
char* file=NULL;
char strToken[20];
int fileLength=0;
int i,j;
struct entryType *headEntry,*tailEntry;
struct digitTable *headDigit,*tailDigit;
struct tokenType *headToken, *tailToken;
char *keywords[]={"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"}; //32個關鍵字
int gotoTable[30][7]={0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
5,0,6,0,7,0,0,
0,0,0,10,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,11,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,13,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,19,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,26,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,27,
0,0,0,0,0,0,28,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0,
0,0,0,0,0,0,0};//goto表
int actionTable[30][14]={1001,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1002,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,1003,0,
0,0,0,0,1004,0,0,0,0,0,0,0,0,0,
0,1008,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,4,0,1009,0,0,0,0,0,0,0,0,
0,0,0,3,0,3,0,0,0,0,0,0,0,0,
0,0,0,1012,0,0,0,0,0,0,0,0,0,0,
0,0,0,6,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,-1,
0,0,0,1014,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,1015,1016,0,0,0,0,0,0,
0,0,0,0,0,0,8,8,0,0,0,0,0,0,
0,0,0,2,0,2,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1017,0,0,0,0,0,
0,0,0,5,0,5,0,0,0,0,0,0,0,0,
0,0,0,1018,0,0,0,0,0,0,0,0,0,0,
0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
0,0,0,0,0,0,7,7,0,0,0,0,0,0,
0,0,0,0,0,0,1023,0,0,1024,1025,0,0,0,
0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
0,0,0,0,0,0,13,0,0,13,13,0,13,0,
0,0,0,0,0,0,14,0,0,14,14,0,14,0,
0,0,0,9,0,9,0,0,0,0,0,0,0,0,
0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
0,0,1022,1021,0,0,0,0,0,0,0,1020,0,0,
0,0,0,0,0,0,0,0,0,1024,1025,0,1029,0,
0,0,0,0,0,0,10,0,0,10,1025,0,10,0,
0,0,0,0,0,0,11,0,0,11,11,0,11,0,
0,0,0,0,0,0,12,0,0,12,12,0,12,0};//action表
struct tokenType* position;
struct place_E
{
char strName[16];
int value;
}place_E[32];
int nextQuad=0;//下一四元組
int nextList_P, nextList_S,nextList_D;
int quad_M;
char relop[16];
char type_T[16];
int list_L[32]; //變量地址
char tempVariable[32][16];
int num_E=0, num_L=0;
int tempNum=0;
void panner(int i,Stack tokenStack);
void readGrammar();
char getCharacter();
void recogId(char);
void recogDigit(char);
void recogOther(char);
void f1();
void f2();
void f3();
void f4();
void f5();
void f6();
void f7(Stack tokenStack);
void f8(Stack tokenStack);
void f9(Stack tokenStack);
void f10();
void f11();
void f12();
void f13(Stack tokenStack);
void f14(Stack tokenStack);
//初始化符號表
void initRecord()
{
int i;
char ch;
int j=0, k=0;
FILE *inFile;
for(i = 0; i < 15; i++)
record[i].id = i;
if((inFile=fopen("symbol.txt","r"))==NULL)
{
printf("Cannot open file.");
getchar();
exit(0);
}
while((ch = getc(inFile)) != EOF ) {
while((ch != '\n') && (ch != EOF)) {
if((ch != ' ') && (ch != '\t'))
record[j].symbol[k++] = ch;
ch = getc(inFile);
}
record[j++].symbol[k] = '\0';
k = 0;
}
fclose(inFile);
}
//插入數字
void insertDigit(int Digit)
{
struct digitTable* tempDigitTable;
tempDigitTable = (struct digitTable*) malloc(sizeof(struct digitTable));
tempDigitTable->address = digit;
tempDigitTable->digit = Digit;
tempDigitTable->next = NULL;
if(headDigit == NULL) {
headDigit = tailDigit = tempDigitTable;
digit++;
} else {
tailDigit = tailDigit->next = tempDigitTable;
digit++;
}
}
//插入token字
void insertToken(int id,int entry)
{
struct tokenType *tempToken;
tempToken= (struct tokenType*) malloc(sizeof(struct tokenType));
tempToken->id = id;
tempToken->entry = entry;
tempToken->next = NULL;
if(headToken == NULL) headToken = tailToken = tempToken;
else tailToken = tailToken->next = tempToken;
}
//詞法分析
void Scan()
{
struct stat buffer;
int i = 0;
char ch;
char filename[40];
FILE *inFile;
printf("Please input the file name:");
gets(filename);
stat("filename", &buffer);
file = (char*)malloc(sizeof(buffer.st_size));
if((inFile=fopen("source.txt","r"))==NULL)
{
printf("Cannot open file.");
getchar();
exit(0);
}
while((ch = getc(inFile)) != EOF)
file[i++] = ch;
fclose(inFile) ;
file[i++] = '\0';
fileLength = i;
initRecord();
printf("\n--------------詞法分析----------------\n");
while((ch = getCharacter()) != '\0') {
if((ch != '\n') && (ch != ' ') && (ch != '\t')) {
if( islower(ch) || isupper(ch) || ch == '_' )
recogId(ch);
else if(isdigit(ch))
recogDigit(ch);
else
recogOther(ch);
};
}
insertToken(13,-1);
}
int Reserve()
{
int i,b=0;
for(i=0;i<32;i++)
{
if(strcmp(strToken,keywords[i])==0)
b=i;
}
return b;
}
void recogId(char ch)
{
int i = 0;
int code;
int keyword = 0;
strcpy(strToken,"");
while(islower(ch) || isupper(ch) || isdigit(ch)) {
strToken[i] = ch;
ch = getCharacter();
i++;
}
strToken[i] = '\0';
cursor--;
row--;
code = Reserve();
if (code)
printf("%s\t關鍵字\n",strToken);
else
printf("%s\t標識符\n",strToken);
for(i = 0; i < 13; i++) {
if(strcmp(record[i].symbol,strToken) == 0) {
insertToken(record[i].id, -1);
keyword = 1;
}
}
if(!keyword) {
struct entryType *head, * tempEntry;
int word = 0;
if(headEntry == NULL) {
head = (struct entryType*)malloc(sizeof(struct entryType));
strcpy(head->idName, strToken);
head->address = entry;
head->type = NULL;
head->next = NULL;
headEntry = tailEntry = head;
entry++;
insertToken(3, entry - 1);
}
else {
tempEntry = headEntry;
while(tempEntry != NULL) {
if(strcmp(tempEntry->idName, strToken) == 0) {
insertToken(3, tempEntry->address);
word = 1;
}
tempEntry = tempEntry->next;
}
if(!word) {
head = (struct entryType*)malloc(sizeof(struct entryType));
strcpy(head->idName, strToken);
head->address = entry;
head->type = NULL;
head->next = NULL;
tailEntry = tailEntry->next = head;
entry++;
insertToken(3, entry - 1);
}
}
}
}
//識別數字
void recogDigit(char ch)
{
int i = 0;
do {
i = i * 10 + ch - '0';
ch = getCharacter();
}while(isdigit(ch));
row--;
cursor--;
printf("%d\t常 數\n",i);
insertDigit(i);
insertToken(2, digit - 1);
}
//識別界限符、運算符
void recogOther(char ch)
{
switch(ch) {
case '{': insertToken(4, -1); printf("%c\t界限符\n",ch); break;
case '}': insertToken(5, -1); printf("%c\t界限符\n",ch); break;
case ';': insertToken(6, -1); printf("%c\t界限符\n",ch); break;
case ',': insertToken(7, -1); printf("%c\t界限符\n",ch); break;
case '=': insertToken(8, -1); printf("%c\t運算符\n",ch); break;
case '+': insertToken(9, -1); printf("%c\t運算符\n",ch); break;
case '*': insertToken(10, -1); printf("%c\t運算符\n",ch); break;
case '(': insertToken(11, -1); printf("%c\t界限符\n",ch); break;
case ')': insertToken(12, -1); printf("%c\t界限符\n",ch); break;
default:break;}
}
//查找下一個字符
char getCharacter()
{
if(file[cursor] == '\n') {
row = 1;
line++;
cursor++;
} else {
row++;
cursor++;
}
return file[cursor];
}
//讀入語法分析結果
void readGrammar()
{
int i = 1;
FILE *in;
if((in=fopen("grammar.txt","r"))==NULL){
printf("Cannot open file.");
getchar();
exit(0);
}
else{
while(fgets(grammar[i].string, 20, in)!=NULL){
grammar[i].id = i;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -