问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

词法扫描器 c c++

发布网友 发布时间:2022-04-24 01:57

我来回答

1个回答

热心网友 时间:2023-10-20 09:15

类似的词法分析器,你可以在这基础上加上一些功能。mlex.c内容如下:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <conio.h>#include <assert.h>#include "lex.h"
char strToken[30]; //字符数组,存放构成单词符号的字符串。int lvalue; //单词的内码值keyword keywords[]={"switch",$SWITCH,"case",$CASE,"if",$IF,"else",$ELSE,"do",$DO,"while",$WHILE,"stop",$STOP,"end",$END,"var",$VAR,"dim",$DIM,"char",$CHAR,0,0,}; //关键字表symbol ctable[200]; //常数表symbol vtable[200]; //符号表(标识符)char inbuf[300]; //扫描缓冲区int sp; //起点指示器int ep; //扫描指示器int lineno; //行计数器FILE *fsrc;
char GetChar(){//从扫描缓冲区第一个缓冲区从inbuf中读一个字符,实现双输入缓冲。//[0]到inbuf[149],第二个缓冲区从inbuf[150]到inbuf[299],//每次从源文件读一个缓冲区大小的内容,分析完当前工作缓冲区内容时把源文件读入//另一个缓冲区,另一个缓冲区成为工作缓冲区int i = 0;char ch;if ((ep == 150)||(ep == 300)){ep = ep%300;while (((inbuf[i+ep]=fgetc(fsrc))!=NULL) && (i<150))i++;}ch = inbuf[ep];ep++;return ch;}char GetBC(){//从扫描缓冲区读字符,过滤空格、制表和回车符号char ch = GetChar();while ((ch==' ') || (ch=='\n') || (ch=='\t')){if (ch=='\n')lineno++;ch = GetChar();}return ch;}void Concat(char str[], char ch){//将字符ch添加到符号串str的尾部str[strlen(str)] = ch;}bool isLetter(char ch){//判断ch是否字母if (((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z')))return true;return false;}bool isDigit(char ch){//判断ch是否数字if ((ch>='0')&&(ch<='9'))return true;return false;}
int Reserve(char* str){//如str是保留字,返回保留字种别号//否则返回0int i = 0;while (keywords[i].code != 0){if (strcmp(str,keywords[i].name) == 0)return keywords[i].code;i++;}return 0;}void Retract(){//从扫描输入缓冲区回退一个字符if (ep==0)ep = 299;elseep--;}
int InsertID(char *str){//如符号表中已有str标识符,返回记录号,//否则将str加到符号表中,返回记录号int i = 0;while ((vtable[i].number!=0) && (i<200)){if (strcmp(str,vtable[i].name) == 0)return vtable[i].number;i++;}if (i<200){vtable[i].number = i+1;strcpy(vtable[i].name, str);return vtable[i].number;}return 0;}int InsertConst(char *str){//如常数表中已有str常数,返回记录号,//否则将str加到常数表中,返回记录号int i = 0;while ((ctable[i].number!=0) && (i<200)){if (strcmp(str,ctable[i].name) == 0)return ctable[i].number;i++;}if (i<200){ctable[i].number = i+1;strcpy(ctable[i].name, str);return ctable[i].number;}return 0;}void ProcError(){printf("%i 行有错误\n", lineno);}int Lex(){//从扫描缓冲区中识别出一个单词,返回单词种别号,//构成的单词的符号串保留在strToken中,//单词的值保留在lvalue中。strToken和lvalue为全局变量。int code;char ch;
memset(strToken, 0, 30);ch = GetBC();sp = ep-1;lvalue = 0;if (isLetter(ch)){while (isLetter(ch) || isDigit(ch)){Concat(strToken, ch);ch = GetChar();}Retract();code = Reserve(strToken);if (code == 0){lvalue = InsertID(strToken);return $ID;}return code;}else if (isDigit(ch)){while (isDigit(ch)){Concat(strToken, ch);ch = GetChar();} if (ch == '.' ) { Concat(strToken, ch); if(!isDigit(GetChar())) {ProcError(); return $END;} Retract(); while(isDigit(GetChar())) { Retract(); Concat(strToken,GetChar()); Retract(); GetChar(); } InsertConst(strToken); return $FLOAT; }Retract();lvalue = InsertConst(strToken);return $INT;}

else if (ch == '='){ch = GetChar();if (ch == '=') return $EQ;Retract();return $ASSIGN;}else if (ch == '+') return $PLUS;else if (ch == ';') return $SEMICOLON;else if (ch == '(') return $LPAR;else if (ch == ')') return $RPAR;else if (ch == '{') return $LBRACE;else if (ch == '}') return $RBRACE;
else if (ch == '*') {ch = GetChar();if (ch == '*') return $POWER;Retract();return $STAR;}else if (ch == EOF) return $END; else{ProcError();return $END;}}void main(){token aToken;int i = 0;char strName[256];FILE *fcon = fopen("const.txt","w+");FILE *ftoken = fopen("token.txt","w+");FILE *fsym = fopen("symbol.txt","w+");printf("请输入源文件名(enter结束):\n");scanf("%s",strName);fsrc = fopen(strName,"r");if (fsrc == NULL){printf("找不到源文件src.txt\n");exit(1);}if ((ftoken == NULL) || (fcon == NULL) || \(fsym == NULL)){printf("不能创建输出文件const.txt,token.txt,symbol.txt\n");exit(1);}/*读源文件入缓冲区*/while ((i<150) && ((inbuf[i]=fgetc(fsrc)) != EOF))i++;
/*词法分析开始*/ep = 0;lineno = 1;aToken.label = 0;aToken.code = Lex();aToken.addr = lvalue;printf("单词序列:\n");while (aToken.code != $END){//单词输出到文件fprintf(ftoken, "(%3d,%3d)", aToken.code, aToken.addr);//单词输出到屏幕printf("(%3d,%3d) ", aToken.code, aToken.addr);aToken.label++;aToken.code = Lex();aToken.addr = lvalue;}/*词法分析结束,输出符号表和常数表到symbol.txt、const.txt文件并显示在屏幕*/i = 0;printf("\n符号表:\n");while (vtable[i].number != 0){fprintf(fsym, "(%3d,%s)", vtable[i].number, vtable[i].name);printf("(%3d,%s)", vtable[i].number, vtable[i].name);i++;}i = 0;printf("\n常数表:\n");while (ctable[i].number != 0){fprintf(fcon, "(%3d,%s)", ctable[i].number, ctable[i].name);printf("(%3d,%s)", ctable[i].number, ctable[i].name);i++;}fclose(fsrc);fclose(fsym);fclose(fcon);fclose(ftoken);printf("\n词法分析结束,按任意键\n");getch();}

lex.h头文件内容如下:typedef struct token{int label;char name[30];//组成单词的字符串int code;int addr;}token;
typedef struct symbol{int number;char name[30];//组成标识符或常数的字符串} symbol;
typedef struct keyword{char name[30]; //组成关键字的字符串int code;} keyword;
//定义一些常量enum TVAL {$WHILE=1,$IF,$ELSE,$SWITCH,$CASE,$DO,$STOP,$END,$ID,$INT,$EQ,$ASSIGN,$PLUS, \$STAR,$POWER,$COMMA,$LPAR,$RPAR,$SEMICOLON,$LBRACE, \$RBRACE,$VAR,$DIM,$FLOAT,$CHAR};

热心网友 时间:2023-10-20 09:15

类似的词法分析器,你可以在这基础上加上一些功能。mlex.c内容如下:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <conio.h>#include <assert.h>#include "lex.h"
char strToken[30]; //字符数组,存放构成单词符号的字符串。int lvalue; //单词的内码值keyword keywords[]={"switch",$SWITCH,"case",$CASE,"if",$IF,"else",$ELSE,"do",$DO,"while",$WHILE,"stop",$STOP,"end",$END,"var",$VAR,"dim",$DIM,"char",$CHAR,0,0,}; //关键字表symbol ctable[200]; //常数表symbol vtable[200]; //符号表(标识符)char inbuf[300]; //扫描缓冲区int sp; //起点指示器int ep; //扫描指示器int lineno; //行计数器FILE *fsrc;
char GetChar(){//从扫描缓冲区第一个缓冲区从inbuf中读一个字符,实现双输入缓冲。//[0]到inbuf[149],第二个缓冲区从inbuf[150]到inbuf[299],//每次从源文件读一个缓冲区大小的内容,分析完当前工作缓冲区内容时把源文件读入//另一个缓冲区,另一个缓冲区成为工作缓冲区int i = 0;char ch;if ((ep == 150)||(ep == 300)){ep = ep%300;while (((inbuf[i+ep]=fgetc(fsrc))!=NULL) && (i<150))i++;}ch = inbuf[ep];ep++;return ch;}char GetBC(){//从扫描缓冲区读字符,过滤空格、制表和回车符号char ch = GetChar();while ((ch==' ') || (ch=='\n') || (ch=='\t')){if (ch=='\n')lineno++;ch = GetChar();}return ch;}void Concat(char str[], char ch){//将字符ch添加到符号串str的尾部str[strlen(str)] = ch;}bool isLetter(char ch){//判断ch是否字母if (((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z')))return true;return false;}bool isDigit(char ch){//判断ch是否数字if ((ch>='0')&&(ch<='9'))return true;return false;}
int Reserve(char* str){//如str是保留字,返回保留字种别号//否则返回0int i = 0;while (keywords[i].code != 0){if (strcmp(str,keywords[i].name) == 0)return keywords[i].code;i++;}return 0;}void Retract(){//从扫描输入缓冲区回退一个字符if (ep==0)ep = 299;elseep--;}
int InsertID(char *str){//如符号表中已有str标识符,返回记录号,//否则将str加到符号表中,返回记录号int i = 0;while ((vtable[i].number!=0) && (i<200)){if (strcmp(str,vtable[i].name) == 0)return vtable[i].number;i++;}if (i<200){vtable[i].number = i+1;strcpy(vtable[i].name, str);return vtable[i].number;}return 0;}int InsertConst(char *str){//如常数表中已有str常数,返回记录号,//否则将str加到常数表中,返回记录号int i = 0;while ((ctable[i].number!=0) && (i<200)){if (strcmp(str,ctable[i].name) == 0)return ctable[i].number;i++;}if (i<200){ctable[i].number = i+1;strcpy(ctable[i].name, str);return ctable[i].number;}return 0;}void ProcError(){printf("%i 行有错误\n", lineno);}int Lex(){//从扫描缓冲区中识别出一个单词,返回单词种别号,//构成的单词的符号串保留在strToken中,//单词的值保留在lvalue中。strToken和lvalue为全局变量。int code;char ch;
memset(strToken, 0, 30);ch = GetBC();sp = ep-1;lvalue = 0;if (isLetter(ch)){while (isLetter(ch) || isDigit(ch)){Concat(strToken, ch);ch = GetChar();}Retract();code = Reserve(strToken);if (code == 0){lvalue = InsertID(strToken);return $ID;}return code;}else if (isDigit(ch)){while (isDigit(ch)){Concat(strToken, ch);ch = GetChar();} if (ch == '.' ) { Concat(strToken, ch); if(!isDigit(GetChar())) {ProcError(); return $END;} Retract(); while(isDigit(GetChar())) { Retract(); Concat(strToken,GetChar()); Retract(); GetChar(); } InsertConst(strToken); return $FLOAT; }Retract();lvalue = InsertConst(strToken);return $INT;}

else if (ch == '='){ch = GetChar();if (ch == '=') return $EQ;Retract();return $ASSIGN;}else if (ch == '+') return $PLUS;else if (ch == ';') return $SEMICOLON;else if (ch == '(') return $LPAR;else if (ch == ')') return $RPAR;else if (ch == '{') return $LBRACE;else if (ch == '}') return $RBRACE;
else if (ch == '*') {ch = GetChar();if (ch == '*') return $POWER;Retract();return $STAR;}else if (ch == EOF) return $END; else{ProcError();return $END;}}void main(){token aToken;int i = 0;char strName[256];FILE *fcon = fopen("const.txt","w+");FILE *ftoken = fopen("token.txt","w+");FILE *fsym = fopen("symbol.txt","w+");printf("请输入源文件名(enter结束):\n");scanf("%s",strName);fsrc = fopen(strName,"r");if (fsrc == NULL){printf("找不到源文件src.txt\n");exit(1);}if ((ftoken == NULL) || (fcon == NULL) || \(fsym == NULL)){printf("不能创建输出文件const.txt,token.txt,symbol.txt\n");exit(1);}/*读源文件入缓冲区*/while ((i<150) && ((inbuf[i]=fgetc(fsrc)) != EOF))i++;
/*词法分析开始*/ep = 0;lineno = 1;aToken.label = 0;aToken.code = Lex();aToken.addr = lvalue;printf("单词序列:\n");while (aToken.code != $END){//单词输出到文件fprintf(ftoken, "(%3d,%3d)", aToken.code, aToken.addr);//单词输出到屏幕printf("(%3d,%3d) ", aToken.code, aToken.addr);aToken.label++;aToken.code = Lex();aToken.addr = lvalue;}/*词法分析结束,输出符号表和常数表到symbol.txt、const.txt文件并显示在屏幕*/i = 0;printf("\n符号表:\n");while (vtable[i].number != 0){fprintf(fsym, "(%3d,%s)", vtable[i].number, vtable[i].name);printf("(%3d,%s)", vtable[i].number, vtable[i].name);i++;}i = 0;printf("\n常数表:\n");while (ctable[i].number != 0){fprintf(fcon, "(%3d,%s)", ctable[i].number, ctable[i].name);printf("(%3d,%s)", ctable[i].number, ctable[i].name);i++;}fclose(fsrc);fclose(fsym);fclose(fcon);fclose(ftoken);printf("\n词法分析结束,按任意键\n");getch();}

lex.h头文件内容如下:typedef struct token{int label;char name[30];//组成单词的字符串int code;int addr;}token;
typedef struct symbol{int number;char name[30];//组成标识符或常数的字符串} symbol;
typedef struct keyword{char name[30]; //组成关键字的字符串int code;} keyword;
//定义一些常量enum TVAL {$WHILE=1,$IF,$ELSE,$SWITCH,$CASE,$DO,$STOP,$END,$ID,$INT,$EQ,$ASSIGN,$PLUS, \$STAR,$POWER,$COMMA,$LPAR,$RPAR,$SEMICOLON,$LBRACE, \$RBRACE,$VAR,$DIM,$FLOAT,$CHAR};

热心网友 时间:2023-10-20 09:15

类似的词法分析器,你可以在这基础上加上一些功能。mlex.c内容如下:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <conio.h>#include <assert.h>#include "lex.h"
char strToken[30]; //字符数组,存放构成单词符号的字符串。int lvalue; //单词的内码值keyword keywords[]={"switch",$SWITCH,"case",$CASE,"if",$IF,"else",$ELSE,"do",$DO,"while",$WHILE,"stop",$STOP,"end",$END,"var",$VAR,"dim",$DIM,"char",$CHAR,0,0,}; //关键字表symbol ctable[200]; //常数表symbol vtable[200]; //符号表(标识符)char inbuf[300]; //扫描缓冲区int sp; //起点指示器int ep; //扫描指示器int lineno; //行计数器FILE *fsrc;
char GetChar(){//从扫描缓冲区第一个缓冲区从inbuf中读一个字符,实现双输入缓冲。//[0]到inbuf[149],第二个缓冲区从inbuf[150]到inbuf[299],//每次从源文件读一个缓冲区大小的内容,分析完当前工作缓冲区内容时把源文件读入//另一个缓冲区,另一个缓冲区成为工作缓冲区int i = 0;char ch;if ((ep == 150)||(ep == 300)){ep = ep%300;while (((inbuf[i+ep]=fgetc(fsrc))!=NULL) && (i<150))i++;}ch = inbuf[ep];ep++;return ch;}char GetBC(){//从扫描缓冲区读字符,过滤空格、制表和回车符号char ch = GetChar();while ((ch==' ') || (ch=='\n') || (ch=='\t')){if (ch=='\n')lineno++;ch = GetChar();}return ch;}void Concat(char str[], char ch){//将字符ch添加到符号串str的尾部str[strlen(str)] = ch;}bool isLetter(char ch){//判断ch是否字母if (((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z')))return true;return false;}bool isDigit(char ch){//判断ch是否数字if ((ch>='0')&&(ch<='9'))return true;return false;}
int Reserve(char* str){//如str是保留字,返回保留字种别号//否则返回0int i = 0;while (keywords[i].code != 0){if (strcmp(str,keywords[i].name) == 0)return keywords[i].code;i++;}return 0;}void Retract(){//从扫描输入缓冲区回退一个字符if (ep==0)ep = 299;elseep--;}
int InsertID(char *str){//如符号表中已有str标识符,返回记录号,//否则将str加到符号表中,返回记录号int i = 0;while ((vtable[i].number!=0) && (i<200)){if (strcmp(str,vtable[i].name) == 0)return vtable[i].number;i++;}if (i<200){vtable[i].number = i+1;strcpy(vtable[i].name, str);return vtable[i].number;}return 0;}int InsertConst(char *str){//如常数表中已有str常数,返回记录号,//否则将str加到常数表中,返回记录号int i = 0;while ((ctable[i].number!=0) && (i<200)){if (strcmp(str,ctable[i].name) == 0)return ctable[i].number;i++;}if (i<200){ctable[i].number = i+1;strcpy(ctable[i].name, str);return ctable[i].number;}return 0;}void ProcError(){printf("%i 行有错误\n", lineno);}int Lex(){//从扫描缓冲区中识别出一个单词,返回单词种别号,//构成的单词的符号串保留在strToken中,//单词的值保留在lvalue中。strToken和lvalue为全局变量。int code;char ch;
memset(strToken, 0, 30);ch = GetBC();sp = ep-1;lvalue = 0;if (isLetter(ch)){while (isLetter(ch) || isDigit(ch)){Concat(strToken, ch);ch = GetChar();}Retract();code = Reserve(strToken);if (code == 0){lvalue = InsertID(strToken);return $ID;}return code;}else if (isDigit(ch)){while (isDigit(ch)){Concat(strToken, ch);ch = GetChar();} if (ch == '.' ) { Concat(strToken, ch); if(!isDigit(GetChar())) {ProcError(); return $END;} Retract(); while(isDigit(GetChar())) { Retract(); Concat(strToken,GetChar()); Retract(); GetChar(); } InsertConst(strToken); return $FLOAT; }Retract();lvalue = InsertConst(strToken);return $INT;}

else if (ch == '='){ch = GetChar();if (ch == '=') return $EQ;Retract();return $ASSIGN;}else if (ch == '+') return $PLUS;else if (ch == ';') return $SEMICOLON;else if (ch == '(') return $LPAR;else if (ch == ')') return $RPAR;else if (ch == '{') return $LBRACE;else if (ch == '}') return $RBRACE;
else if (ch == '*') {ch = GetChar();if (ch == '*') return $POWER;Retract();return $STAR;}else if (ch == EOF) return $END; else{ProcError();return $END;}}void main(){token aToken;int i = 0;char strName[256];FILE *fcon = fopen("const.txt","w+");FILE *ftoken = fopen("token.txt","w+");FILE *fsym = fopen("symbol.txt","w+");printf("请输入源文件名(enter结束):\n");scanf("%s",strName);fsrc = fopen(strName,"r");if (fsrc == NULL){printf("找不到源文件src.txt\n");exit(1);}if ((ftoken == NULL) || (fcon == NULL) || \(fsym == NULL)){printf("不能创建输出文件const.txt,token.txt,symbol.txt\n");exit(1);}/*读源文件入缓冲区*/while ((i<150) && ((inbuf[i]=fgetc(fsrc)) != EOF))i++;
/*词法分析开始*/ep = 0;lineno = 1;aToken.label = 0;aToken.code = Lex();aToken.addr = lvalue;printf("单词序列:\n");while (aToken.code != $END){//单词输出到文件fprintf(ftoken, "(%3d,%3d)", aToken.code, aToken.addr);//单词输出到屏幕printf("(%3d,%3d) ", aToken.code, aToken.addr);aToken.label++;aToken.code = Lex();aToken.addr = lvalue;}/*词法分析结束,输出符号表和常数表到symbol.txt、const.txt文件并显示在屏幕*/i = 0;printf("\n符号表:\n");while (vtable[i].number != 0){fprintf(fsym, "(%3d,%s)", vtable[i].number, vtable[i].name);printf("(%3d,%s)", vtable[i].number, vtable[i].name);i++;}i = 0;printf("\n常数表:\n");while (ctable[i].number != 0){fprintf(fcon, "(%3d,%s)", ctable[i].number, ctable[i].name);printf("(%3d,%s)", ctable[i].number, ctable[i].name);i++;}fclose(fsrc);fclose(fsym);fclose(fcon);fclose(ftoken);printf("\n词法分析结束,按任意键\n");getch();}

lex.h头文件内容如下:typedef struct token{int label;char name[30];//组成单词的字符串int code;int addr;}token;
typedef struct symbol{int number;char name[30];//组成标识符或常数的字符串} symbol;
typedef struct keyword{char name[30]; //组成关键字的字符串int code;} keyword;
//定义一些常量enum TVAL {$WHILE=1,$IF,$ELSE,$SWITCH,$CASE,$DO,$STOP,$END,$ID,$INT,$EQ,$ASSIGN,$PLUS, \$STAR,$POWER,$COMMA,$LPAR,$RPAR,$SEMICOLON,$LBRACE, \$RBRACE,$VAR,$DIM,$FLOAT,$CHAR};

热心网友 时间:2023-10-20 09:15

类似的词法分析器,你可以在这基础上加上一些功能。mlex.c内容如下:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <conio.h>#include <assert.h>#include "lex.h"
char strToken[30]; //字符数组,存放构成单词符号的字符串。int lvalue; //单词的内码值keyword keywords[]={"switch",$SWITCH,"case",$CASE,"if",$IF,"else",$ELSE,"do",$DO,"while",$WHILE,"stop",$STOP,"end",$END,"var",$VAR,"dim",$DIM,"char",$CHAR,0,0,}; //关键字表symbol ctable[200]; //常数表symbol vtable[200]; //符号表(标识符)char inbuf[300]; //扫描缓冲区int sp; //起点指示器int ep; //扫描指示器int lineno; //行计数器FILE *fsrc;
char GetChar(){//从扫描缓冲区第一个缓冲区从inbuf中读一个字符,实现双输入缓冲。//[0]到inbuf[149],第二个缓冲区从inbuf[150]到inbuf[299],//每次从源文件读一个缓冲区大小的内容,分析完当前工作缓冲区内容时把源文件读入//另一个缓冲区,另一个缓冲区成为工作缓冲区int i = 0;char ch;if ((ep == 150)||(ep == 300)){ep = ep%300;while (((inbuf[i+ep]=fgetc(fsrc))!=NULL) && (i<150))i++;}ch = inbuf[ep];ep++;return ch;}char GetBC(){//从扫描缓冲区读字符,过滤空格、制表和回车符号char ch = GetChar();while ((ch==' ') || (ch=='\n') || (ch=='\t')){if (ch=='\n')lineno++;ch = GetChar();}return ch;}void Concat(char str[], char ch){//将字符ch添加到符号串str的尾部str[strlen(str)] = ch;}bool isLetter(char ch){//判断ch是否字母if (((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z')))return true;return false;}bool isDigit(char ch){//判断ch是否数字if ((ch>='0')&&(ch<='9'))return true;return false;}
int Reserve(char* str){//如str是保留字,返回保留字种别号//否则返回0int i = 0;while (keywords[i].code != 0){if (strcmp(str,keywords[i].name) == 0)return keywords[i].code;i++;}return 0;}void Retract(){//从扫描输入缓冲区回退一个字符if (ep==0)ep = 299;elseep--;}
int InsertID(char *str){//如符号表中已有str标识符,返回记录号,//否则将str加到符号表中,返回记录号int i = 0;while ((vtable[i].number!=0) && (i<200)){if (strcmp(str,vtable[i].name) == 0)return vtable[i].number;i++;}if (i<200){vtable[i].number = i+1;strcpy(vtable[i].name, str);return vtable[i].number;}return 0;}int InsertConst(char *str){//如常数表中已有str常数,返回记录号,//否则将str加到常数表中,返回记录号int i = 0;while ((ctable[i].number!=0) && (i<200)){if (strcmp(str,ctable[i].name) == 0)return ctable[i].number;i++;}if (i<200){ctable[i].number = i+1;strcpy(ctable[i].name, str);return ctable[i].number;}return 0;}void ProcError(){printf("%i 行有错误\n", lineno);}int Lex(){//从扫描缓冲区中识别出一个单词,返回单词种别号,//构成的单词的符号串保留在strToken中,//单词的值保留在lvalue中。strToken和lvalue为全局变量。int code;char ch;
memset(strToken, 0, 30);ch = GetBC();sp = ep-1;lvalue = 0;if (isLetter(ch)){while (isLetter(ch) || isDigit(ch)){Concat(strToken, ch);ch = GetChar();}Retract();code = Reserve(strToken);if (code == 0){lvalue = InsertID(strToken);return $ID;}return code;}else if (isDigit(ch)){while (isDigit(ch)){Concat(strToken, ch);ch = GetChar();} if (ch == '.' ) { Concat(strToken, ch); if(!isDigit(GetChar())) {ProcError(); return $END;} Retract(); while(isDigit(GetChar())) { Retract(); Concat(strToken,GetChar()); Retract(); GetChar(); } InsertConst(strToken); return $FLOAT; }Retract();lvalue = InsertConst(strToken);return $INT;}

else if (ch == '='){ch = GetChar();if (ch == '=') return $EQ;Retract();return $ASSIGN;}else if (ch == '+') return $PLUS;else if (ch == ';') return $SEMICOLON;else if (ch == '(') return $LPAR;else if (ch == ')') return $RPAR;else if (ch == '{') return $LBRACE;else if (ch == '}') return $RBRACE;
else if (ch == '*') {ch = GetChar();if (ch == '*') return $POWER;Retract();return $STAR;}else if (ch == EOF) return $END; else{ProcError();return $END;}}void main(){token aToken;int i = 0;char strName[256];FILE *fcon = fopen("const.txt","w+");FILE *ftoken = fopen("token.txt","w+");FILE *fsym = fopen("symbol.txt","w+");printf("请输入源文件名(enter结束):\n");scanf("%s",strName);fsrc = fopen(strName,"r");if (fsrc == NULL){printf("找不到源文件src.txt\n");exit(1);}if ((ftoken == NULL) || (fcon == NULL) || \(fsym == NULL)){printf("不能创建输出文件const.txt,token.txt,symbol.txt\n");exit(1);}/*读源文件入缓冲区*/while ((i<150) && ((inbuf[i]=fgetc(fsrc)) != EOF))i++;
/*词法分析开始*/ep = 0;lineno = 1;aToken.label = 0;aToken.code = Lex();aToken.addr = lvalue;printf("单词序列:\n");while (aToken.code != $END){//单词输出到文件fprintf(ftoken, "(%3d,%3d)", aToken.code, aToken.addr);//单词输出到屏幕printf("(%3d,%3d) ", aToken.code, aToken.addr);aToken.label++;aToken.code = Lex();aToken.addr = lvalue;}/*词法分析结束,输出符号表和常数表到symbol.txt、const.txt文件并显示在屏幕*/i = 0;printf("\n符号表:\n");while (vtable[i].number != 0){fprintf(fsym, "(%3d,%s)", vtable[i].number, vtable[i].name);printf("(%3d,%s)", vtable[i].number, vtable[i].name);i++;}i = 0;printf("\n常数表:\n");while (ctable[i].number != 0){fprintf(fcon, "(%3d,%s)", ctable[i].number, ctable[i].name);printf("(%3d,%s)", ctable[i].number, ctable[i].name);i++;}fclose(fsrc);fclose(fsym);fclose(fcon);fclose(ftoken);printf("\n词法分析结束,按任意键\n");getch();}

lex.h头文件内容如下:typedef struct token{int label;char name[30];//组成单词的字符串int code;int addr;}token;
typedef struct symbol{int number;char name[30];//组成标识符或常数的字符串} symbol;
typedef struct keyword{char name[30]; //组成关键字的字符串int code;} keyword;
//定义一些常量enum TVAL {$WHILE=1,$IF,$ELSE,$SWITCH,$CASE,$DO,$STOP,$END,$ID,$INT,$EQ,$ASSIGN,$PLUS, \$STAR,$POWER,$COMMA,$LPAR,$RPAR,$SEMICOLON,$LBRACE, \$RBRACE,$VAR,$DIM,$FLOAT,$CHAR};
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
求这图片原图或者主角 出自哪一边电影或者电视剧 哪位大神知道这张图原版在吗?求原版。。。 在word中加下划线时第一次出现一条下划线第二次怎么就出现两条... 诛仙2资料站里的宠物展示能在npc买到吗 求一些诛仙2中的可以变为人形的宠物名字 诛仙2 神域的神农殿里,这是什么东西 诛仙2宠物元神问题 诛仙2 商城 中 宠物元神 怎么比 宠物 还贵啊?宠物元神是干什么的啊... 电热水器怎么安固定花洒 猛鬼夜惊魂剧情介绍 Polo plus得到过什么奖项? 我为什么要做幼儿教师500字左右的论文 数码宝贝 装甲进化 罗马音 求一篇3000字左右的幼师毕业论文 ~~!急求~~! 2.4g和5g要不要合并?对生活有什么影响么? 求幼师论文3000字不低于10篇文献 求计算机休眠代码 如何做一名幼儿教师论文 如何做一名优秀的幼儿园教师论文 好多电脑专业术语(指英文的),特别是一些英文大写字母缩写,在哪里有专门... 五香卤豆干的做法步骤图,五香卤豆干怎么做 病毒是怎么让杀毒软件无法启动的? 卤水煮豆干的做法,卤水煮豆干怎么做好吃,卤水 如何做一名合格的幼儿教师 论文 rstandard意思 幼师心得论文 我的任务管理器打开后为什么只出现用户信息 关于c语言计算器的问题 搜幼师实习论文、三千字! 卤味豆腐干如何做 根据幼教专业,写一篇关于理想的论文!1500字! 《RS江湖》Runescape怎么玩如何赚钱? 幼教毕业论文怎么写啊 c++问题求解 php怎么获取钉钉员工授权信息? vb游戏修改器(没分了,大侠) c# 使用Forms.Message类型或者调用API的方法 java 关于file reading and token 绍兴的房子可以在萧山的银行做房子抵押贷款吗?有区域限制吗 萧山典当行房贷利息是几离? 小伙背30年房贷去相亲被嫌弃,30年房贷的压力有多大? 小伙背着月供8700元的30年房贷相亲,姑娘被吓跑,你能接受高房贷吗? 带三十年房贷相亲被骂小伙发声:“我还得起,我买房没错”,他真的没错吗? 手机设置字体 步步高音乐手机,滑盖的有哪些?还有它们的简单介绍? 步步高音乐手机有哪几款是滑盖的? 步步高i188滑盖手机内存多大?功能怎么样? 步步高音乐手机刚出的那款滑盖手机怎么样 详细资料 步步高的滑盖手机有哪些 请问各位,步步高的哪款手机是滑盖的,实用的,价格不超过850的,跪求…重金