📄 syntaxanalysis.c
字号:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include "GLOBAL.H"
#define STRMAX 3000
#define SYMMAX 300
FILE *fp;
char buffer[SIZE]; // 缓冲区
struct entry symtable[SYMMAX];
char lexemes[STRMAX];
int lastentry = 0;
char* forward; // 向前指针
char* lexeme_beginning; // 词素开始指针
char c;
int state = 0, start = 0;
int lexical_value = 0; // install_id() 和 install_num()返回的指针
char* token_beginning = 0; // 词素中首符号的索引
int lineno = 1;
int tokenval = NONE;
char lexbuf[BSIZE];
char *parent;
char digit[BSIZE];
char alp[BSIZE];
int d=0;a=0;
int isk=0;
struct entry terminal[]=
{
"if",IF,
"then",THEN,
"else",ELSE,
"while",WHILE,
"do",DO,
"begin",BEGIN,
"end",END,
"no",NONE
};
char list();
char list1();
char stmt();
char expr(e);
char expr1();
char term(t);
char term1();
char factor();
void MatchBeginEnd();
void MatchIfThenElse();
char ignorspace(c);
char match(c1);
// 出错记录函数
void error(char* m)
{
printf(" LINE %d: %s\n", lineno, m);
}
/* 将标识符插入符号表中 */
int insert(char s[], int tok)
{
int len,lastchar=-1;
len = strlen(s);
if(lastentry + 1 >= SYMMAX) error("symtable full");
if(lastchar + len + 1 >= STRMAX) error("lexemes array full");
lastentry++;
symtable[lastentry].token = tok;
symtable[lastentry].lexptr = &lexemes[lastchar+1];
lastchar = lastchar+len+1;
strcpy(symtable[lastentry].lexptr, s);
return lastentry;
}
/* 将关键字填入符号表 */
void init()
{
struct entry *p;
for(p = terminal/*keywords*/; p->token != NONE; p++)
{
insert(p->lexptr, p->token);
}
}
/* 填充缓冲区 */
void filetobuffer()
{
fread(buffer,1,SIZE-1,fp);
buffer[SIZE-1]='\0';
}
/* 打印缓冲区 */
void printbuffer()
{
printf("-----------------------The buffer is:-----------------------\n%s\n",buffer);
printf("------------------------------------------------------------\n");
}
/* 回退amount个位置 */
char retract(int amount)
{ if(*forward != '\x0')
{
forward -= amount;
}
return *forward;
}
/* 返回超前扫描字符 */
char nextchar()
{
if(forward == NULL) /* 刚开始扫描 */
{
forward = buffer;
}
else forward++;
if(*forward == '\x0')
{
if( forward == &(buffer[SIZE - 1]) )
{
fread(buffer,1,SIZE/2 - 1,fp);
buffer[SIZE/2 - 1] = '\x0';
forward = buffer;
return *forward;
}
else return '\x0'; // 文件已经处理完了
}
return *forward;
}
/* 打印符号表 */
void printsymtable()
{
int index;
printf("\nThe symtable is:\n");
printf("lexptr\ttoken");
for(index = 1;symtable[index].lexptr != NULL;index++ )
{
printf("\n%s\t%d",symtable[index].lexptr,symtable[index].token);
}
}
/* 试图修复程序错误 */
void recover()
{
c = nextchar();
while(c != '\n')
{
c = nextchar();
if(c == '\x0')
{
return;
}
}
lineno++;
lexeme_beginning = forward + 1;
state = 0;
}
/* 查找符号表中是否已记录s标识符 */
int lookup(s)
char s[];
{
int p;
for(p = lastentry; p > 0; p--)
{
if(strcmp(symtable[p].lexptr, s) == 0)
return p;
}
return 0;
}
/* 插入符号表,这里只是简单输出 */
int install_id()
{
int b,p=0; int i,scmp;
char* pointer=lexeme_beginning;
b=0;
for(; pointer != (forward + 1); pointer++,b++)
{
if(*pointer == '\x0')
{
if(pointer == &(buffer[SIZE - 1]))
pointer = buffer;
}
lexbuf[b] = *pointer;
if(b >= BSIZE) error("compiler error");
// printf("%c",*pointer);
}
lexbuf[b] = EOS;
for(i = 0; i <lastentry; i++)
{
scmp =strcmp(/*keywords[i]*/terminal[i].lexptr, alp);//original use 'lexbuf' instead of 'alp
if(scmp!=0){
isk=1;
// continue;
}
else if(scmp==0) {
isk=2;
break;
}
}
if(isk==1) //not keyword
{
//some sentence add here ...if possible
//c5=1;
}
if(isk==2) //keyword
{
//some sentence add here ...if possible
}
p = lookup(lexbuf);
// if(p == 0) p = insert(lexbuf, ID);
tokenval = p;
lexeme_beginning = forward;
return symtable[p].token;
}
/* 用来存放num表项的值,这里只是简单输出 */
void install_num()
{
char* p = lexeme_beginning;
if(forward < lexeme_beginning)
{
printf("forward run too further than lexeme_beginning(in install_num())!");
getch();
exit(1);
}
/*
printf("< NUM... ,");
for(; p <= forward; p++)
{
if(*p != '\x0')
{
printf("%c",*p);
}
}
putchar('>');
putchar('\n');
*/
}
/* 当前模式匹配失败,开始下一轮匹配 */
int fail()
{
forward = lexeme_beginning;
if(*forward == '\x0')
{
start = 100;
}
retract(1);
switch(start)
{
case 0: start= 9; break;
case 9: start= 12; break;
case 12: start= 20; break;
case 20: start= 25; break;
case 25: start= 28; break;
case 28:
error("Unknow Symbol!");//compiler error
recover();
start = 0;
break;
default:
// printf("The file has been lexed!\n");
printf("Fail...\n");
getch();
exit(0);
break;
}
return start;
}
/* 得到文件的下一个词素 */
char nexttoken()
{
while(1) {
switch (state)
{
case 0: c = nextchar(); //c is lookahead character
if (isspace(c) || c=='\r' || c== '\n')
{
if(c=='\n') lineno++;
state = 0;
lexeme_beginning++; //advance beginning of lexeme
}
else if (c == '<') state = 1;
else if (c == '=')
{
//state = 5;
printf("< RELOP,EQ>\n");
lexical_value = EQ;
// return RELOP;
return c;
}
else if (c == '>') state = 6;
else state = fail();
break;
case 1: c = nextchar();
if (c=='=')
{
// state=2;
printf("< RELOP,LE>\n");
lexical_value = LE;
// return RELOP;
return c;
}
else if(c=='>')
{
// state=3;
printf("< RELOP,NE>\n");
lexical_value = NE;
// return RELOP;
return c;
}
else
{
// state=4;
retract(1);
printf("< RELOP,LT>\n");
lexical_value = LT;
// return RELOP;
return c;
}
case 6: c = nextchar();
if(c=='=')
{
// state=7;
printf("< RELOP,GE>\n");
lexical_value = GE;
// return GE;
return c;
}
else
{
// state=8;
retract(1);
printf("< RELOP,GT>\n");
lexical_value = GT;
// return RELOP;
return c;
}
break;
case 9: c = nextchar(); //c=ignorspace(c);
a=0; // alphabet state 9 to 11
alp[a]=c;
a++;
if (isalpha(c))
state = 10;
else {
a--;
state=fail();
}
break;
case 10: c = nextchar();
alp[a]=c;
a++;
if (isalpha(c) || isdigit(c))
state = 10;
else state = 11;
break;
case 11:
c=retract(1);
alp[a-1]='\0';
// lexical_value = install_id();
// return ( gettoken(lexical_value) ); //read token name from st
install_id();
return c;
// return ID;
case 12: c=nextchar(); d=0;
digit[d]=c;d++;
if(isdigit(c))
{
state=13;}
else {
d--;
state=fail();
}
break;
case 13: c=nextchar();
digit[d]=c;d++;
if(isdigit(c)) state = 13;
else if(c == '.') state = 14;
else if(c == 'E') state=16;
else {
d--;
state=fail();
}
break;
case 14: c=nextchar();
digit[d]=c;d++;
if(isdigit(c)) state=15;
else {
d--;
state=fail();
}
break;
case 15: c=nextchar();
digit[d]=c;d++;
if(isdigit(c)) state=15;
else if (c=='E') state=16;
else {
d--;
state=fail();
}
break;
case 16: c=nextchar();
digit[d]=c;d++;
if(c=='+'||c=='-') state=17;
else if (c=isdigit(c)) state=18;
else {
d--;
state=fail();
}
break;
case 17: c=nextchar();
digit[d]=c;d++;
if(isdigit(c)) state=18;
else {
d--;
state=fail();
}
break;
case 18: c=nextchar();
digit[d]=c;d++;
if(isdigit(c)) state=18;
else
{
//state=19; //digit.digitE+-digit
digit[d-1]='\0';
c=retract(1);
install_num();
return c;
// return NUM;
}
break;
case 20: c=nextchar(); d=0;
digit[d]=c;d++;
if(isdigit(c)) state=21;
else {
d--;
state=fail();
}
break;
case 21: c=nextchar();
digit[d]=c;d++;
if(isdigit(c)) state=21;
else if (c=='.') state=22;
else {
d--;
state=fail();
}
break;
case 22: c=nextchar();
digit[d]=c;d++;
if(isdigit(c)) state=23;
else {
d--;
state=fail();
}
break;
case 23: c=nextchar();
digit[d]=c; d++;
if (isdigit(c)) state=23;
/***/ else if(c=='E')
{
c=retract(1);
while(isdigit(c)|c=='.'){c=retract(1);}
state=12;
}
else
{
//state=24; //digit.digit
digit[d-1]='\0';
c=retract(1);
install_num();
return c;
// return NUM;
}
break;
case 25: c=nextchar(); d=0;
digit[d]=c;d++;
if(isdigit(c))
state=26;
else {
d--;
state=fail();
}
break;
case 26: c=nextchar();
digit[d]=c; d++;
if(isdigit(c)) state=26;
/***/ else if(c=='.')
{
c=retract(1);
while(isdigit(c)){c=retract(1);}
state=20;
}
/***/ else if(c=='E')
{
c=retract(1);
while(isdigit(c)){c=retract(1);}
state=12;
}
else
{
//state=27
digit[d-1]='\0'; //digit
c=retract(1);
install_num();
return c;
// return NUM;
}
break;
default: c=nextchar();
{
// printf("< ,%c> ",c);
// error("Unknow Symbol!");
return c;
}
break;
}
}
}
#include "ParsingTree.h" // Insert parsingtree.h file here...
int main()
{
int completed = 0;
printf(" Syntax Analysis BY J04120017\n");
printf("list -> list ; stmt | stmt\n");
printf("stmt -> IF expr THEN stmt\n");
printf(" | IF expr THEN stmt ELSE stmt\n");
printf(" | WHILE expr DO stmt\n");
printf(" | BEGIN list END\n");
printf(" | ID := expr\n");
printf("expr -> expr + term | term\n");
printf("term -> term * factor | factor\n");
printf("factor -> (expr) | ID | NUM\n");
printf("\nPLS INPUT:\n");
/**/
init();
gets(buffer);
// printbuffer(); //print the content of the original file
forward = NULL;
lexeme_beginning = buffer;
while(!completed)
{
// state = 0;
start = 0;
printf("\nConstruct the tree from the LIST...\n\n");
parent=list();
//if(c==EOS)
printf("\n\nfinished!\n");
return;
lexeme_beginning = forward;
lexeme_beginning++;
}
fclose(fp);
free(lexemes);
free(symtable);
free(buffer);
free(lexbuf);
free(parent);
printsymtable();
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -