1、定义目标语言的可用符号表
关键字:if,else,for,while,do,int,read,write,return 标识符:①标识符由字母、数字组成;②不能把c语言关键字作为标识符;③标识符对大小写敏感;④首字符只能是字母,不能是数字。 常数:无符号整数值。 运算符:+、-、*、/、==、<=、>=、!=、= 界符:,、;、{、}、(、)
2、定义程序输入输出
程序输入:依照c语言程序规则输入,以txt文本形式存储; 程序输出:程序依照 类型 值 的形式每行一个进行输出,例如 int int。
3、代码
(1)头文件 analysis.h
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define keywordSum 9
char * keyword[ keywordSum] = { "if" , "else" , "for" , "while" , "do" , "int" , "read" , "write" , "return" } ;
char singleword[ 50 ] = "!+-*(){};,:" ;
char doubleword[ 10 ] = "><=!&|" ;
extern char Scanin[ 300 ] , Scanout[ 300 ] ;
extern FILE * fin , * fout;
int TESTscan ( )
{
char ch , token[ 40 ] ;
int es = 0 , j, n;
printf ( "请输人源程序文件名(包括路径):" ) ;
scanf ( "%s" , Scanin) ;
printf ( "请输人词法分析输出文件名(包括路径):" ) ;
scanf ( "%s" , Scanout) ;
if ( ( fin = fopen ( Scanin , "r" ) ) == NULL )
{
printf ( "\n打开词法分析输人文件出错!\n" ) ;
return ( 1 ) ;
}
if ( ( fout = fopen ( Scanout , "w" ) ) == NULL )
{
printf ( "\n创建词法分析输出文件出错!\n" ) ;
return ( 2 ) ;
}
ch = getc ( fin) ;
while ( ch != EOF )
{
while ( ch == ' ' || ch == '\n' || ch == '\t' ) ch = getc ( fin) ;
if ( isalpha ( ch) )
{
token[ 0 ] = ch; j = 1 ;
ch = getc ( fin) ;
while ( isalnum ( ch) )
{
token[ j++ ] = ch;
ch = getc ( fin) ;
}
token[ j] = '\0' ;
n = 0 ;
while ( ( n < keywordSum) && strcmp ( token, keyword[ n] ) ) n++ ;
if ( n >= keywordSum)
fprintf ( fout, "%s\t%s\n" , "ID" , token) ;
else
fprintf ( fout, "%s\t%s\n" , token, token) ;
} else if ( isdigit ( ch) )
{
token[ 0 ] = ch; j = 1 ;
ch = getc ( fin) ;
while ( isdigit ( ch) )
{
token[ j++ ] = ch;
ch = getc ( fin) ;
}
token[ j] = '\0' ;
fprintf ( fout, "%s\t%s\n" , "NUM" , token) ;
} else if ( strchr ( singleword, ch) > 0 )
{
token[ 0 ] = ch; token[ 1 ] = '\0' ;
ch = getc ( fin) ;
fprintf ( fout, "%s\t%s\n" , token, token) ;
} else if ( strchr ( doubleword, ch) > 0 )
{
token[ 0 ] = ch;
ch = getc ( fin) ;
if ( ch == '=' )
{
token[ 1 ] = ch; token[ 2 ] = '\0' ;
ch = getc ( fin) ;
} else if ( ch == '&' )
{
token[ 1 ] = ch; token[ 2 ] = '\0' ;
ch = getc ( fin) ;
}
else if ( ch == '|' )
{
token[ 1 ] = ch; token[ 2 ] = '\0' ;
ch = getc ( fin) ;
} else
token[ 1 ] = '\0' ;
fprintf ( fout, "%s\t%s\n" , token, token) ;
} else if ( ch == '/' )
{
ch = getc ( fin) ;
if ( ch == '*' )
{
char ch1;
ch1 = getc ( fin) ;
do
{
ch = ch1; ch1 = getc ( fin) ;
} while ( ( ch != '*' || ch1 != '/' ) && ch1 != EOF ) ;
ch = getc ( fin) ;
} else
{
token[ 0 ] = '/' ; token[ 1 ] = '\0' ;
fprintf ( fout, "%s\t%s\n" , token, token) ;
}
} else
{
token[ 0 ] = ch; token[ 1 ] = '\0' ;
ch = getc ( fin) ;
es = 3 ;
fprintf ( fout, "%s\t%s\n" , "ERROR" , token) ;
}
}
fclose ( fin) ;
fclose ( fout) ;
return ( es) ;
}
(2)测试 main.cpp
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "analysis.h"
extern int TESTscan ( ) ;
char Scanin[ 300 ] , Scanout[ 300 ] ;
FILE * fin, * fout;
int main ( ) {
int es = 0 ;
es = TESTscan ( ) ;
if ( es > 0 )
printf ( "词法分析有错,编译停止!" ) ;
else
printf ( "词法分析成功!\n" ) ;
}
4、测试
(1)输入文件 test.txt
(2)运行
(3)输入文件 result.txt