编译原理实验一
作者:互联网
编译原理实验一
实验指导书源程序的改进版
程序一:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define ID 7
#define INT 8
#define REAL 9
#define LT 10
#define LE 11
#define EQ 12
#define NE 13
#define GT 14
#define GE 15
#define IS 16
#define PL 17
#define MI 18
#define MU 19
#define DI 20
char TOKEN[20];
void report_error(char *s)
{
printf("Having Error: %s", *s);
}
void out(int x, char *s)
{
switch (x)
{
case 7:
{
printf("%s,%s\n", "ID", *s);
break;
}
case 8:
{
printf("%s,%s\n", "INT", *s);
break;
}
case 10:
{
printf("%s,%s\n", "LT", *s);
break;
}
case 11:
{
printf("%s,%s\n", "LE", *s);
break;
}
case 12:
{
printf("%s,%s\n", "EQ", *s);
break;
}
case 13:
{
printf("%s,%s\n", "NE", *s);
break;
}
case 14:
{
printf("%s,%s\n", "GT", *s);
break;
}
case 15:
{
printf("%s,%s\n", "GE", *s);
break;
}
case 16:
{
printf("%s,%s\n", "IS", *s);
break;
}
case 17:
{
printf("%s,%s\n", "PL", *s);
break;
}
case 18:
{
printf("%s,%s\n", "MI", *s);
break;
}
case 19:
{
printf("%s,%s\n", "MU", *s);
break;
}
case 20:
{
printf("%s,%s\n", "DI", *s);
break;
}
default:
{
printf("%s,%s\n", KeyWordTable[x], *s);
break;
}
}
}
/* 建立保留字表 */
#define MAX_KEY_NUMBER 20 /*关键字的数量*/
#define KEY_WORD_END "waiting for your expanding" /*关键字结束标记*/
char *KeyWordTable[MAX_KEY_NUMBER] = {"begin", "end", "if", "then", "else", "switch", "case", KEY_WORD_END};
/* 查保留字表,判断是否为关键字
不是关键字,返回0,是关键字,返回n+1, n为关键字数组中所找到的相同的关键字的索引位置*/
int lookup(char *token)
{
int n = 0;
while (strcmp(KeyWordTable[n], KEY_WORD_END)) /*如果比较到最后一位,也就是KEY_WORD_END,也就是已经确定都没有相同的,返回0*/
{
/*strcmp比较两串是否相同,若相同返回0*/
/*相等:strcmp函数返回0,加上!后为:TRUE 进入if内部执行语句;
不相等: strcmp返回其他正数或负数,这些返回值都等价于:TRUE ,加上!后,都为:FALSE 不进入if内部语句*/
if (!strcmp(KeyWordTable[n], token))
{
return n + 1; /*根据单词分类码表I,设置正确的关键字类别码,并返回此类别码的值*/
break;
}
n++;
}
return 0; /*单词不是关键字,而是标识符*/
}
void scanner_example(FILE *fp)
{
char ch;
int i = 0;
int c = 0;
ch = fgetc(fp); /*取出一个字符*/
/*首字符为字母,字母数字混杂*/
if (isalpha(ch)) /*是否是字母*/
{
TOKEN[0] = ch;
ch = fgetc(fp); /*取出下一个字符*/
i = 1;
while (isalnum(ch)) /*是否是字母或者数字*/
{
TOKEN[i] = ch;
i++;
ch = fgetc(fp); /*取出一个字符*/
}
/*跳出循环之后,fp指针指向的字符,不再是数字或者字母*/
TOKEN[i] = '\0';
fseek(fp, -1, 1); /*fp指针从当前位置往前挪一位*/
c = lookup(TOKEN); /*判断是否是关键字,不是的话返回0*/
if (c == 0)
out(ID, TOKEN);
else
out(c - 1, " "); /*因为lookup函数返回值为n+1*/
}
/*首字符是数字,整型数字*/
else if (isdigit(ch)) /*是否是数字*/
{
TOKEN[0] = ch;
ch = fgetc(fp); /*取出第二个字符*/
i = 1;
while (isdigit(ch)) /*后面取出的字符都依然是数字*/
{
TOKEN[i] = ch;
i++;
ch = fgetc(fp);
}
/*跳出循环之后,fp指针指向的字符,不再是数字*/
TOKEN[i] = '\0';
fseek(fp, -1, 1); /*fp指针从当前位置往前挪一位*/
out(INT, TOKEN);
}
else
{
switch (ch)
{
case '<':
{
ch = fgetc(fp);
if (ch == '=')
out(LE, " ");
else if (ch == '>')
out(NE, " ");
else
{ /*下一位不是=或者> :当做只有< */
fseek(fp, -1, 1); /*fp指针从当前位置往前挪一位*/
out(LT, " ");
}
break;
}
case '=':
{
out(EQ, " ");
break;
}
case '>':
{
ch = fgetc(fp);
if (ch == '=')
out(GE, " ");
else
{ /*下一位不是= :当做只有> */
fseek(fp, -1, 1); /*fp指针从当前位置往前挪一位*/
out(GT, " ");
}
break;
}
case ':':
{
ch = fgetc(fp);
if (ch == '=')
{
out(IS, " ");
}
else
{ /*冒号后面跟着的不是等号的话*/
report_error(':');
fseek(fp, -1, 1);
}
}
case '+':
{
out(PL, " ");
}
case '-':
{
out(MI, " ");
}
case '*':
{
out(MU, " ");
}
case '/':
{
out(DI, " ");
}
default:
{
report_error(ch);
break;
}
}
}
return;
}
程序二
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include<stdlib.h>
#define DIGIT 1
#define POINT 2
#define OTHER 3
#define POWER 4
#define PLUS 5
#define MINUS 6
#define UCON 7
/*Suppose the class number of unsigned constant is 7
假设无符号常量的类数为7*/
#define ClassOther 200
#define EndState -1
int w, n, p, e, d;
int Class;
/*Used to indicate class of the word
用来表示单词的类别*/
int ICON;
float FCON;
static int CurrentState;
/*Used to present current state, the initial value:0
用于表示当前状态,初始值:0*/
int GetChar(void);
int EXCUTE(int, int);
int HandleOtherWord(void)
{
return ClassOther;
}
int HandleError(void)
{
printf("Error!\n");
return 0;
}
int GetChar(void)
{
int c;
c = getchar();
if (isdigit(c))
{
d = c -'0';
return DIGIT;
}
if (c =='.')
return POINT;
if (c =='E'|| c =='e')
return POWER;
if (c =='+')
return PLUS;
if (c =='-')
return MINUS;
return OTHER;
}
int EXCUTE(int state, int symbol)
{
switch (state)
{
case 0:
switch (symbol)
{
case DIGIT:
n = 0;
p = 0;
e = 1;
w = d;
CurrentState = 1;
Class = UCON;
break;
case POINT:
w = 0;
n = 0;
p = 0;
e = 1;
CurrentState = 3;
Class = UCON;
break;
default:
HandleOtherWord();
Class = ClassOther;
CurrentState = EndState;
}
break;
case 1:
switch (symbol)
{
case DIGIT:
w = w * 10 + d;
break; //CurrentState=1
case POINT:
CurrentState = 2;
break;
case POWER:
CurrentState = 4;
break;
default:
ICON = w;
CurrentState = EndState;
}
break;
case 2:
switch (symbol)
{
case DIGIT:
n++;
w = w * 10 + d;
break;
case POWER:
CurrentState = 4;
break;
default:
FCON = w * pow(10, e * p - n);
CurrentState = EndState;
}
break;
case 3:
switch (symbol)
{
case DIGIT:
n++;
w = w * 10 + d;
CurrentState = 2;
break;
default:
HandleError();
CurrentState = EndState;
}
break;
case 4:
switch (symbol)
{
case DIGIT:
p = p * 10 + d;
CurrentState = 6;
break;
case MINUS:
e = -1;
CurrentState = 5;
break;
case PLUS:
CurrentState = 5;
break;
default:
HandleError();
CurrentState = EndState;
}
break;
case 5:
switch (symbol)
{
case DIGIT:
p = p * 10 + d;
CurrentState = 6;
break;
default:
HandleError();
CurrentState = EndState;
}
break;
case 6:
switch (symbol)
{
case DIGIT:
p = p * 10 + d;
break;
default:
FCON = w * pow(10, e * p - n);
CurrentState = EndState;
}
break;
}
return CurrentState;
}
int LEX(void)
{
int ch;
CurrentState = 0;
while (CurrentState != EndState)
{
ch = GetChar();
EXCUTE(CurrentState, ch);
}
//return Class;
printf("w: %d n: %d p: %d e: %d d: %d", w, n, p, e, d);
printf("\n ICON: %.3f, FCON: %.3f CLASS: %d", ICON, FCON, Class);
}
int main(){
LEX();
system("pause");
}
但是程序二是建立在手动输入上的,需要将程序一二做一个合体改造
程序:
waiting
标签:case,ch,int,break,编译,实验,原理,CurrentState,define 来源: https://blog.csdn.net/caoxiaobao1207/article/details/121042574