编译器练习:找出C程序中声明的变量,关键字和自然数
2009-03-31 12:24
337 查看
1.源代码
//glovar.h
#ifndef _GLOVAR_H_
#define _GLOBAR_H_
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXTOKEN 40
extern FILE *fps;
extern FILE *fpt;
char tokenStr[MAXTOKEN+1];
typedef enum {
INIT,
INNUM,
INID,
IN_MARK,
IN_MARK_SEG,IN_MARK_SEG1,
IN_MARK_LINE,
DONE
}TokenState;
typedef enum {
ID,NUM,/*JUDGE SYMBOL*/
IF,ELSE,DO,WHILE,SWITCH,CASE,INT,LONG,DOUBLE,FLOAT,CHAR,BREAK,
EQ,LS,LE,GT,GE,NE, //EQ =,LS <,LE <= ,GT >, GE >=, NE !=
ASSIGN, //'='
ADD,SUB,MUL,DIV,//OP + , - , * , / ,
INC,DEC,
LC,RC, // '(' ')'
LR,RR, // '[' ']'
LS,RS, // '{' '}'
OR,AND,NOT, // '|' '&' '!'
SEMI,// ';'
SHARP,//'#'
ENDFILE
}TokenType;
#endif
//scan.h
#ifndef _SCAN_H_
#define _SCAN_H_
TokenType GetToken(void);
#endif
//scan.c
#include "glovar.h"
#include "scan.h"
int line=1;
static struct {
char *str;
TokenType tok;
}kw[12]={{"if",IF},{"else",ELSE},{"do",DO},{"while",WHILE},{"break",BREAK}, {"switch",SWITCH},{"case",CASE},
{"int",INT},{"char",CHAR},{"float",FLOAT},{"double",DOUBLE},{"long",LONG}};
int reservelookup(char *s){
int i;
for(i=0;i<12;i++){
if(strcmp(s,kw[i].str)==0)
return 1;
}
return 0;
}
TokenType GetToken(void){
int tokenBufferIndex=0;
char ch;
TokenType tt;
TokenState state=INIT;
while(state!=DONE){
ch=getc(fps);
switch(state){
case INIT: if(isdigit(ch))
{
state=INNUM;
tokenStr[tokenBufferIndex++]=ch;
}
else if (isalpha(ch)){
state=INID;
tokenStr[tokenBufferIndex++]=ch;}
else if((ch==' ')||ch=='/t') state=INIT;
else {
switch(ch){
case '=' : ch=getc(fps);
if(ch=='=') tt=EQ;
else {
ungetc(ch,fps);
tt= ASSIGN;
}
break;
case '<' : ch=getc(fps);
if(ch=='=') tt=LE;
else if(ch=='>') tt=NE;
else {
ungetc(ch,fps);
tt= LS;
}
break;
case '>' : ch=getc(fps);
if(ch=='=') tt= GE;
else {
ungetc(ch,fps);
tt= GT;
}
break;
case '|': tt=OR;
state=DONE;
break;
case '&': tt=AND;
state=DONE;
break;
case '!': tt=NOT;
state=DONE;
break;
case '+': ch=getc(fps);
if(ch=='+') tt= INC;
else{
ungetc(ch,fps);
tt= ADD;
break;
}
case '-': ch=getc(fps);
if(ch=='-') tt= DEC;
else{
ungetc(ch,fps);
tt=SUB;
break;
}
case '*':
tt= MUL;
state=DONE;
break;
case '/': state=IN_MARK;
break;
case '/n': line++;
break;
case '#': tt=SHARP;
break;
case ';' : tt= SEMI;
state=DONE;
break;
case '(' : tt= LC;
state=DONE;
break;
case ')' : tt= RC;
state=DONE;
break;
case '[' : tt= LR;
state=DONE;
break;
case ']' : tt= RR;
state=DONE;
break;
case '{' : tt= LS;
state=DONE;
break;
case '}' : tt= RS;
state=DONE;
break;
case EOF:
tt=ENDFILE;
state=DONE;
break;
default : break;
}
}
break;
case IN_MARK:
if(ch=='*') state= IN_MARK_SEG;
else if(ch=='/') state= IN_MARK_LINE;
else {
ungetc(ch,fps);
tt=DIV;
state=DONE;
}
break;
case IN_MARK_SEG:
if(ch=='*') state=IN_MARK_SEG1;
break;
case IN_MARK_SEG1:
if(ch=='/') state=INIT;
break;
case IN_MARK_LINE:
if(ch=='/n') state=INIT;
break;
case INNUM: if(isdigit(ch))
tokenStr[tokenBufferIndex++]=ch;
else
{ tokenStr[tokenBufferIndex]='/0';
state=DONE;
ungetc(ch,fps);
tt=NUM;
}
break;
case INID: if(isalpha(ch))
tokenStr[tokenBufferIndex++]=ch;
else{
tokenStr[tokenBufferIndex]='/0';
state=DONE;
ungetc(ch,fps);
tt=ID;
}
break;
case DONE: break;
}
}
if(tt==ID){
if(reservelookup(tokenStr))
fprintf(fpt,"Get Keywords -->%s/n/n",tokenStr);
else
fprintf(fpt,"Get ID -->%s/n/n",tokenStr);
}
else if(tt==NUM)
fprintf(fpt,"Get NUM -->%s/n",tokenStr);
return tt;
}
//main.c
#include "glovar.h"
#include "scan.h"
/*
programed by:alex shoal
edit date:2009-4-22, Sunday
revision:2
****************
*Question:gettoken practice
****************
*/
FILE *fps; //* file point of source
FILE *fpt; //* file point of target
int main(int argc, char *argv[]){
TokenType tp;
int i=0;
fpt=stdout;
if (argc != 2){
printf("Usage: %s filename/n", argv[0]);
exit(1);
}
if ((fps = fopen(argv[1], "r")) == NULL){
printf("Can't open file :%s/n", argv[1]);
exit(1);
}
if ((fpt = fopen("out.txt", "w+")) == NULL){
printf("Can't open file :out.txt /n");
exit(1);
}
while (((tp = GetToken()) != ENDFILE)){
fprintf(fpt,"Token %d= %d/n",i++,tp);
}
fclose(fps);
return 0;
}
2.编译
code block 8.02编译
3.输入文件
//filename app.c
//ANSI C exit() prototype
int main(int argc, char *argv[])
{
int ch; // place to store each character as read
FILE *fp; // "file pointer"
long count = 0;
if (argc != 2)
{
printf("Usage: %s filename/n", argv[0]);
exit(1);
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
printf("Can't open %s/n", argv[1]);
exit(1);
}
while ((ch = getc(fp)) != EOF)
{
putchar(ch,stdout); /*same as putchar(ch);
count++;
}
fclose(fp);*/
printf("File %s has %ld characters/n", argv[1], count);
return 0;
}
4.运行
temp app.c
8.结果
Get Keywords -->int
Token 0= 0
Get ID -->main
Token 1= 0
Token 2= 28
Get Keywords -->int
Token 3= 0
Get ID -->argc
Token 4= 0
Get Keywords -->char
Token 5= 0
Token 6= 24
Get ID -->argv
Token 7= 0
Token 8= 30
Token 9= 31
Token 10= 29
Token 11= 32
Get Keywords -->int
Token 12= 0
Get ID -->ch
Token 13= 0
Token 14= 37
Get ID -->FILE
Token 15= 0
Token 16= 24
Get ID -->fp
Token 17= 0
Token 18= 37
Get Keywords -->long
Token 19= 0
Get ID -->count
Token 20= 0
Get NUM -->0
Token 21= 1
Token 22= 37
Get Keywords -->if
Token 23= 0
Token 24= 28
Get ID -->argc
Token 25= 0
Token 26= 36
Get NUM -->2
Token 27= 1
Token 28= 29
Token 29= 32
Get ID -->printf
Token 30= 0
Token 31= 28
Get ID -->Usage
Token 32= 0
Get ID -->s
Token 33= 0
Get ID -->filename
Token 34= 0
Get ID -->n
Token 35= 0
Get ID -->argv
Token 36= 0
Token 37= 30
Get NUM -->0
Token 38= 1
Token 39= 31
Token 40= 29
Token 41= 37
Get ID -->exit
Token 42= 0
Token 43= 28
Get NUM -->1
Token 44= 1
Token 45= 29
Token 46= 37
Token 47= 33
Get Keywords -->if
Token 48= 0
Token 49= 28
Token 50= 28
Get ID -->fp
Token 51= 0
Get ID -->fopen
Token 52= 0
Token 53= 28
Get ID -->argv
Token 54= 0
Token 55= 30
Get NUM -->1
Token 56= 1
Token 57= 31
Get ID -->r
Token 58= 0
Token 59= 29
Token 60= 29
Get ID -->NULL
Token 61= 0
Token 62= 29
Token 63= 32
Get ID -->printf
Token 64= 0
Token 65= 28
Get ID -->Can
Token 66= 0
Get ID -->t
Token 67= 0
Get ID -->open
Token 68= 0
Get ID -->s
Token 69= 0
Get ID -->n
Token 70= 0
Get ID -->argv
Token 71= 0
Token 72= 30
Get NUM -->1
Token 73= 1
Token 74= 31
Token 75= 29
Token 76= 37
Get ID -->exit
Token 77= 0
Token 78= 28
Get NUM -->1
Token 79= 1
Token 80= 29
Token 81= 37
Token 82= 33
Get Keywords -->while
Token 83= 0
Token 84= 28
Token 85= 28
Get ID -->ch
Token 86= 0
Get ID -->getc
Token 87= 0
Token 88= 28
Get ID -->fp
Token 89= 0
Token 90= 29
Token 91= 29
Token 92= 36
Get ID -->EOF
Token 93= 0
Token 94= 29
Token 95= 32
Get ID -->putchar
Token 96= 0
Token 97= 28
Get ID -->ch
Token 98= 0
Get ID -->stdout
Token 99= 0
Token 100= 29
Token 101= 37
Get ID -->printf
Token 102= 0
Token 103= 28
Get ID -->File
Token 104= 0
Get ID -->s
Token 105= 0
Get ID -->has
Token 106= 0
Get ID -->ld
Token 107= 0
Get ID -->characters
Token 108= 0
Get ID -->n
Token 109= 0
Get ID -->argv
Token 110= 0
Token 111= 30
Get NUM -->1
Token 112= 1
Token 113= 31
Get ID -->count
Token 114= 0
Token 115= 29
Token 116= 37
Get ID -->return
Token 117= 0
Get NUM -->0
Token 118= 1
Token 119= 37
Token 120= 33
//glovar.h
#ifndef _GLOVAR_H_
#define _GLOBAR_H_
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXTOKEN 40
extern FILE *fps;
extern FILE *fpt;
char tokenStr[MAXTOKEN+1];
typedef enum {
INIT,
INNUM,
INID,
IN_MARK,
IN_MARK_SEG,IN_MARK_SEG1,
IN_MARK_LINE,
DONE
}TokenState;
typedef enum {
ID,NUM,/*JUDGE SYMBOL*/
IF,ELSE,DO,WHILE,SWITCH,CASE,INT,LONG,DOUBLE,FLOAT,CHAR,BREAK,
EQ,LS,LE,GT,GE,NE, //EQ =,LS <,LE <= ,GT >, GE >=, NE !=
ASSIGN, //'='
ADD,SUB,MUL,DIV,//OP + , - , * , / ,
INC,DEC,
LC,RC, // '(' ')'
LR,RR, // '[' ']'
LS,RS, // '{' '}'
OR,AND,NOT, // '|' '&' '!'
SEMI,// ';'
SHARP,//'#'
ENDFILE
}TokenType;
#endif
//scan.h
#ifndef _SCAN_H_
#define _SCAN_H_
TokenType GetToken(void);
#endif
//scan.c
#include "glovar.h"
#include "scan.h"
int line=1;
static struct {
char *str;
TokenType tok;
}kw[12]={{"if",IF},{"else",ELSE},{"do",DO},{"while",WHILE},{"break",BREAK}, {"switch",SWITCH},{"case",CASE},
{"int",INT},{"char",CHAR},{"float",FLOAT},{"double",DOUBLE},{"long",LONG}};
int reservelookup(char *s){
int i;
for(i=0;i<12;i++){
if(strcmp(s,kw[i].str)==0)
return 1;
}
return 0;
}
TokenType GetToken(void){
int tokenBufferIndex=0;
char ch;
TokenType tt;
TokenState state=INIT;
while(state!=DONE){
ch=getc(fps);
switch(state){
case INIT: if(isdigit(ch))
{
state=INNUM;
tokenStr[tokenBufferIndex++]=ch;
}
else if (isalpha(ch)){
state=INID;
tokenStr[tokenBufferIndex++]=ch;}
else if((ch==' ')||ch=='/t') state=INIT;
else {
switch(ch){
case '=' : ch=getc(fps);
if(ch=='=') tt=EQ;
else {
ungetc(ch,fps);
tt= ASSIGN;
}
break;
case '<' : ch=getc(fps);
if(ch=='=') tt=LE;
else if(ch=='>') tt=NE;
else {
ungetc(ch,fps);
tt= LS;
}
break;
case '>' : ch=getc(fps);
if(ch=='=') tt= GE;
else {
ungetc(ch,fps);
tt= GT;
}
break;
case '|': tt=OR;
state=DONE;
break;
case '&': tt=AND;
state=DONE;
break;
case '!': tt=NOT;
state=DONE;
break;
case '+': ch=getc(fps);
if(ch=='+') tt= INC;
else{
ungetc(ch,fps);
tt= ADD;
break;
}
case '-': ch=getc(fps);
if(ch=='-') tt= DEC;
else{
ungetc(ch,fps);
tt=SUB;
break;
}
case '*':
tt= MUL;
state=DONE;
break;
case '/': state=IN_MARK;
break;
case '/n': line++;
break;
case '#': tt=SHARP;
break;
case ';' : tt= SEMI;
state=DONE;
break;
case '(' : tt= LC;
state=DONE;
break;
case ')' : tt= RC;
state=DONE;
break;
case '[' : tt= LR;
state=DONE;
break;
case ']' : tt= RR;
state=DONE;
break;
case '{' : tt= LS;
state=DONE;
break;
case '}' : tt= RS;
state=DONE;
break;
case EOF:
tt=ENDFILE;
state=DONE;
break;
default : break;
}
}
break;
case IN_MARK:
if(ch=='*') state= IN_MARK_SEG;
else if(ch=='/') state= IN_MARK_LINE;
else {
ungetc(ch,fps);
tt=DIV;
state=DONE;
}
break;
case IN_MARK_SEG:
if(ch=='*') state=IN_MARK_SEG1;
break;
case IN_MARK_SEG1:
if(ch=='/') state=INIT;
break;
case IN_MARK_LINE:
if(ch=='/n') state=INIT;
break;
case INNUM: if(isdigit(ch))
tokenStr[tokenBufferIndex++]=ch;
else
{ tokenStr[tokenBufferIndex]='/0';
state=DONE;
ungetc(ch,fps);
tt=NUM;
}
break;
case INID: if(isalpha(ch))
tokenStr[tokenBufferIndex++]=ch;
else{
tokenStr[tokenBufferIndex]='/0';
state=DONE;
ungetc(ch,fps);
tt=ID;
}
break;
case DONE: break;
}
}
if(tt==ID){
if(reservelookup(tokenStr))
fprintf(fpt,"Get Keywords -->%s/n/n",tokenStr);
else
fprintf(fpt,"Get ID -->%s/n/n",tokenStr);
}
else if(tt==NUM)
fprintf(fpt,"Get NUM -->%s/n",tokenStr);
return tt;
}
//main.c
#include "glovar.h"
#include "scan.h"
/*
programed by:alex shoal
edit date:2009-4-22, Sunday
revision:2
****************
*Question:gettoken practice
****************
*/
FILE *fps; //* file point of source
FILE *fpt; //* file point of target
int main(int argc, char *argv[]){
TokenType tp;
int i=0;
fpt=stdout;
if (argc != 2){
printf("Usage: %s filename/n", argv[0]);
exit(1);
}
if ((fps = fopen(argv[1], "r")) == NULL){
printf("Can't open file :%s/n", argv[1]);
exit(1);
}
if ((fpt = fopen("out.txt", "w+")) == NULL){
printf("Can't open file :out.txt /n");
exit(1);
}
while (((tp = GetToken()) != ENDFILE)){
fprintf(fpt,"Token %d= %d/n",i++,tp);
}
fclose(fps);
return 0;
}
2.编译
code block 8.02编译
3.输入文件
//filename app.c
//ANSI C exit() prototype
int main(int argc, char *argv[])
{
int ch; // place to store each character as read
FILE *fp; // "file pointer"
long count = 0;
if (argc != 2)
{
printf("Usage: %s filename/n", argv[0]);
exit(1);
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
printf("Can't open %s/n", argv[1]);
exit(1);
}
while ((ch = getc(fp)) != EOF)
{
putchar(ch,stdout); /*same as putchar(ch);
count++;
}
fclose(fp);*/
printf("File %s has %ld characters/n", argv[1], count);
return 0;
}
4.运行
temp app.c
8.结果
Get Keywords -->int
Token 0= 0
Get ID -->main
Token 1= 0
Token 2= 28
Get Keywords -->int
Token 3= 0
Get ID -->argc
Token 4= 0
Get Keywords -->char
Token 5= 0
Token 6= 24
Get ID -->argv
Token 7= 0
Token 8= 30
Token 9= 31
Token 10= 29
Token 11= 32
Get Keywords -->int
Token 12= 0
Get ID -->ch
Token 13= 0
Token 14= 37
Get ID -->FILE
Token 15= 0
Token 16= 24
Get ID -->fp
Token 17= 0
Token 18= 37
Get Keywords -->long
Token 19= 0
Get ID -->count
Token 20= 0
Get NUM -->0
Token 21= 1
Token 22= 37
Get Keywords -->if
Token 23= 0
Token 24= 28
Get ID -->argc
Token 25= 0
Token 26= 36
Get NUM -->2
Token 27= 1
Token 28= 29
Token 29= 32
Get ID -->printf
Token 30= 0
Token 31= 28
Get ID -->Usage
Token 32= 0
Get ID -->s
Token 33= 0
Get ID -->filename
Token 34= 0
Get ID -->n
Token 35= 0
Get ID -->argv
Token 36= 0
Token 37= 30
Get NUM -->0
Token 38= 1
Token 39= 31
Token 40= 29
Token 41= 37
Get ID -->exit
Token 42= 0
Token 43= 28
Get NUM -->1
Token 44= 1
Token 45= 29
Token 46= 37
Token 47= 33
Get Keywords -->if
Token 48= 0
Token 49= 28
Token 50= 28
Get ID -->fp
Token 51= 0
Get ID -->fopen
Token 52= 0
Token 53= 28
Get ID -->argv
Token 54= 0
Token 55= 30
Get NUM -->1
Token 56= 1
Token 57= 31
Get ID -->r
Token 58= 0
Token 59= 29
Token 60= 29
Get ID -->NULL
Token 61= 0
Token 62= 29
Token 63= 32
Get ID -->printf
Token 64= 0
Token 65= 28
Get ID -->Can
Token 66= 0
Get ID -->t
Token 67= 0
Get ID -->open
Token 68= 0
Get ID -->s
Token 69= 0
Get ID -->n
Token 70= 0
Get ID -->argv
Token 71= 0
Token 72= 30
Get NUM -->1
Token 73= 1
Token 74= 31
Token 75= 29
Token 76= 37
Get ID -->exit
Token 77= 0
Token 78= 28
Get NUM -->1
Token 79= 1
Token 80= 29
Token 81= 37
Token 82= 33
Get Keywords -->while
Token 83= 0
Token 84= 28
Token 85= 28
Get ID -->ch
Token 86= 0
Get ID -->getc
Token 87= 0
Token 88= 28
Get ID -->fp
Token 89= 0
Token 90= 29
Token 91= 29
Token 92= 36
Get ID -->EOF
Token 93= 0
Token 94= 29
Token 95= 32
Get ID -->putchar
Token 96= 0
Token 97= 28
Get ID -->ch
Token 98= 0
Get ID -->stdout
Token 99= 0
Token 100= 29
Token 101= 37
Get ID -->printf
Token 102= 0
Token 103= 28
Get ID -->File
Token 104= 0
Get ID -->s
Token 105= 0
Get ID -->has
Token 106= 0
Get ID -->ld
Token 107= 0
Get ID -->characters
Token 108= 0
Get ID -->n
Token 109= 0
Get ID -->argv
Token 110= 0
Token 111= 30
Get NUM -->1
Token 112= 1
Token 113= 31
Get ID -->count
Token 114= 0
Token 115= 29
Token 116= 37
Get ID -->return
Token 117= 0
Get NUM -->0
Token 118= 1
Token 119= 37
Token 120= 33
相关文章推荐
- 编译器练习:找出C程序中除注释外的数字并将其值翻倍
- JAVA-变量声明、关键字和类型
- 将变量x声明为unsigned类型,可以保证右移时无论程序在什么机器上运行,左边空位都由0填补
- 编写高质量代码改善C#程序的157个建议——建议113:声明变量前考虑最大值
- (本程序功能:字符串A中找出包含字符串B中所有字符的位置并输出) 在使用全局变量m的时候,输出错误的结果,而用下面局部变量M就没问题。
- [转载]LCC编译器的源程序分析(17)参数变量的声明
- [转载]LCC编译器的源程序分析(21)局部变量的声明
- JavaScript声明变量时为什么要加var关键字
- NSMutableArray 如果只进行了声明,而没有进行初始化,那么程序不会报错,但是,声明的那个变量不起任何作用
- 在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”声明?
- python引用非当前作用于变量时需使用关键字声明一下
- 练习 2-1 编写一个程序以确定分别由 signed 及 unsigned 限定的 char、short、 int 与 long 类型变量的取值范围。
- C++中有关volatile关键字的作用--阻止编译器将其变量优化缓存到寄存器(和线程相关)(转自百度)
- KEIL编译器【C语言编译选项优化等级说明】【支持C99(变量声明在执行语句之后)】【反汇编设置】【C语言联合汇编】
- 变量的声明与定义以及关键字extern的用法
- 【微信小程序】基本语法一:三个声明变量的区别
- 第三天 简单的一个程序剖析,关键字,关于变量,常量,标识符,
- JavaScript声明变量时为什么要加var关键字
- 变量的声明与定义以及关键字extern的用法
- C语言学习笔记----伊能C语言学习笔记----变量可以在程序的三个地方声明