大三的编译原理课程设计。Pascal词法分析器。现在想想学的什么都又还老师啦!
/*******Pascal词法分析器 1.0版 ********
**** 作者:Hainucrzay ******
**** Email: hainucrazy@gmail.com **
**** All rights reserved(C) 2005.12 **
*******************************************/
//pre_define.h
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iostream.h>
#define LT 1
#define LE 6
#define EQ 10
#define NE 14
#define GT 15
#define GE 20
#define BH 21 //branch 分号';'
#define CA 22 //comma 逗号','
#define CO 23 //colon 冒号':'
#define MU 24 //multiple 乘号'*'
#define LB 26 //Left bracket'('
#define RB 27 //right backet')'
#define AS 30 //assign :=
#define MI 44 //minus '-'
#define PS 45 //plus '+'
#define DI 46 //Divid '/'
//用到的结构数组:
struct keyword{ //符号表
char* word;
int value;
}keytab[] = {
"AND", 0,
"BEGIN", 2,
"BOOL", 3, //boolean
"CASE", 4,
"CONST", 5,
"DO", 7,
"ELSE", 8,
"END", 9,
"FALSE", 11, //false
"FOR", 12,
"FUNCTION", 13,
"IF", 16,
"INTEGER", 17, //integer
"LABEL", 18,
"MOD", 25,
"NOT", 28,
"OR", 29,
"PROCEDURE",31,
"PROGRAM", 32,
"TRUE", 37, //true
"THEN", 38,
"TYPE", 39,
"UNTIL", 40,
"VAR", 41,
"WHILE", 42,
"WITH", 43,
};
//scanner.cpp
#include "pre_define.h"
//字符数组TOKEN,用来依次存放一个单词词文中的各个字符
char TOKEN[20];
char *err1="Identifier Overflowed! /n";
//NKEYS:calculate the number of elements in the keytable[] array
int NKEYS = sizeof keytab/sizeof keytab[0];
int lookup(char *keyword); //二分法查找关键字表
int main(int argc,char *argv[])
{
FILE *srcfile=NULL;
int ch;
int i; //TOKEN[i]:max(i)=20
int flag; //判断搜索函数是否成功返回
int countid=50;//关键字的类别码已给出,而标识符类别码统一一码
int countnum=51;//整型数类别码统一一码
if(argc != 2)
{
printf("Usage:%s%s",argv[0]," src-file-name/n");
}else
{//1else
srcfile = fopen(argv[1],"r");
if(srcfile == NULL)
{
printf("Can not open text file /"%s/" !",argv[1]);
}else
{//2else
cout<<endl
<<"*******Pascal词法分析器 v1.0************/n"
<<"*******Author:HainuCrazy 李洋***********/n"
<<"*******StudentNo:2003724035 ************/n"
<<"******Email:hainucrazy@gmail.com********/n"
<<endl
<<"The code of the Program has been splited in TOKEN as Follow:"<<endl
<<"General style:<TOKEN> (<serial number>,[property])"<<endl;
while((ch=fgetc(srcfile)) != EOF)
{//1while
if ( isspace(ch) ) // if is a whitespace character
continue;
else if(isalpha(ch)) /*it must be a identifier*/
{//1elseif
TOKEN[0] = ch;
ch=fgetc(srcfile);
i=1;
while(isalnum(ch)) //an alphanumeric character
{
TOKEN[i]=ch; i++;
ch=fgetc(srcfile);
}
if(i<20){
TOKEN[i]='/0';
fseek(srcfile,-1,SEEK_CUR); //retract
if((flag = lookup(TOKEN)) >= 0) //reference to the keywords
printf("%s/t(%d,-)/n",TOKEN,keytab[flag].value);
else //is a Identifier
printf("%s/t(%d,%s)/n",TOKEN,countid,TOKEN);
}
else printf("%s",err1);
}//1else if
else if(isdigit(ch))
{//2elseif
TOKEN[0]=ch;
ch=fgetc(srcfile); i=1;
while(isdigit(ch)){
TOKEN[i]=ch; i++;
ch=fgetc(srcfile);
}//while
if(i<20){
TOKEN[i]='/0';
fseek(srcfile,-1,SEEK_CUR); //retract
if('0' == TOKEN[0])
printf("%s/t(%s)/n","Invalid num",TOKEN);
//else--0 is the 1st digit num
else printf("%s/t(%d,%s)/n",TOKEN,countnum,TOKEN);
}
else printf("%s",err1);
}//2elseif
else
switch(ch)
{
case '<': ch=fgetc(srcfile);
if(ch == '=') printf("%s/t(%d,-)/n","<=",LE);
else if(ch == '>')
printf("%s/t(%d,-)/n","<>",NE);
else{
fseek(srcfile,-1,SEEK_CUR); //retract
printf("%c/t(%d,-)/n",'<',LT);
}
break;
case ':': ch=fgetc(srcfile);
if(ch == '=') printf("%s/t(%d,-)/n",":=",AS);
else{
fseek(srcfile,-1,SEEK_CUR);
printf("%c/t(%d,-)/n",':',CO);
}
break;
case '>': ch=fgetc(srcfile);
if(ch == '=') printf("%s/t(%d,-)/n","GE");
else
{
fseek(srcfile,-1,SEEK_CUR);
printf("%c/t(%d,-)/n",'>',GT);
}
break;
case '=': printf("%c/t(%d,-)/n",'=',EQ); break;
case ';': printf("%c/t(%d,-)/n",';',BH); break;
case ',': printf("%c/t(%d,-)/n",',',CA); break;
case '(': printf("%c/t(%d,-)/n",'(',LB); break;
case ')': printf("%c/t(%d,-)/n",')',RB); break;
case '-': printf("%c/t(%d,-)/n",'-',MI); break;
case '+': printf("%c/t(%d,-)/n",'+',PS); break;
case '*': printf("%c/t(%d,-)/n",'*',MU); break;
case '/': printf("%c/t(%d,-)/n",'/',DI); break;
default: printf("symbol ( %c ) not defined yet/n",ch);
break;
}//switch
}//1while
}//2else
}//1else
fclose(srcfile);
return 1;
}
int lookup(char *keyword)
{
int low = 0, high = NKEYS - 1, mid;
int Rtnval;
while (low <= high){
mid = (low+high)/2;
/*int StrCmp(LPCTSTR lpStr1,
* LPCTSTR lpStr2);
*Returns zero if the strings are identical.
*/
if((Rtnval=strcmp(keyword,keytab[mid].word)) == 0) return mid;
else if (Rtnval > 0) /*Returns a positive value if the */
low = mid + 1; /*string pointed to by lpStr1 is greater*/
/*than that pointed to by lpStr2. */
else high = mid - 1; /*Returns a negetive value if the */
/*string pointed to by lpStr1 is less*/
/*than that pointed to by lpStr2. */
}
return -1;
}