📄 construe.h
字号:
#include "clanguageinfo.h"
//#include <type>
//#include <stdio.h>
#include <iomanip>
#include <iostream>
#include <fstream>
using namespace std;
#define ERROR_INFO cout<<"\n\nerror line:"<<line_count<<endl
bool construe(char *sourcefile); //construe the C language source
void outcode(char *str);
int iskey(char *str); // Is this str a key ?
int ismacro(char *str); //Is this str a macro ?
void blank(char* &p); //throw blank away
void initOperator(list<W_OPERATOR_STRUCT*> &oplist);
bool findOperator(char *op,W_OPERATOR_STRUCT* &pri);
void dealword(string str1,string str2,int flog,int k=-1); //stor and deal a vocable
/* str1——vocable, str2——attribute, flog——the type of this vocable*/
bool construe(char *sourcefile)
{
char line[256]=""; //read the line
char *p=NULL; //point the line
char token[20]=""; //the courrent string
bool include_bool=false;
int type=-1;
int i=0;
int flog;
int line_count=0;
ifstream fin;
W_OPERATOR_STRUCT* ptr=NULL;
initOperator(oplist);//初始化运算符表
outcode(sourcefile); //输出源程序
//open the file source
fin.open(sourcefile,ios_base::in);
if( !fin.good()){
cout<<"Can not open the file,Thank you!!!"<<endl;
exit(0);
}
while(fin.good()){
fin.getline(line,sizeof(line));
++line_count;
p=line;
blank(p); //throw the front space away
//visit this line,this is the main scouse
while( p<line+strlen(line))
{
i=0;
blank(p);
//////////////////////////////////////
//Is the corrent token a identifier?//
if( isalpha(*p) || (*p=='_') )
{
while( isalnum(*p) || (*p=='_') )
{
token[i++]=*(p++);
}
token[i]='\0';
flog=iskey(token);
if(flog>=0){
dealword(token,"关键字",0,flog);
}
else if(strcmp(token,"main")==0)
dealword(token,"入口函数",0);
else
dealword(token,"标识符",1);
}//end_if
///////////////////////////////
//Is a number?/////////////////
else if(*p>='0'&&*p<='9')
{
while((*p>='0'&&*p<='9') || *p=='.')
token[i++]=*(p++);
token[i]='\0';
dealword(token,"常数",2);
}
///////////////////////////////
//operator or /////////////////
else{
//界符判断,单符号及三符号这里处理,只有二符号查表处理,
//因为三操作符较少,直接可以这里判断,
//这样的好处有:
// 1、从空间上来看,可以减少操作符的存储空间,可以只存储二符号的运算符,
// 2、从效率上来看,大大减少了查表时间,在查表的算法中不用去考虑它是几符号运算符
switch(*p){
case ';' : dealword(";", "分号",6); p++; type=6; break;
case '{' : dealword("{", "域界符", 6); p++; type=6; break;
case '}' : dealword("}", "域界符", 6); p++; type=6; break;
case '#' : //宏开头,下面直读宏标识符
p++;
while(*p==' ') p++;
while(*p>='a'&&*p<='z')
{
token[i++]=*(p++);
}
token[i]='\0';
flog=ismacro(token);
if(flog>=0){
include_bool=true;
dealword("#","宏界符",7,-2);
dealword(token,"宏名称",7,flog);
}
else{
ERROR_INFO;
return false;
}
type=7;
break;
//“ ' ”
case '\'':
i=0;
while(*(++p) != '\'')
token[i++]=*p;
token[i]='\0';
p++;
if(strlen(token)>3){
ERROR_INFO;
return false;
}
dealword(token,"字符",3);
type=3;
break;
//“ " ”
case '\"' :
p++;
i=0;
if(include_bool){
blank(p);
while( isalnum(*p) || (*p=='_') || (*p=='.') || (*p=='-'))
{
token[i++]=*(p++);
}
token[i]='\0';
dealword("\"","界符",7,-2);
dealword(token,"包含的文件",7);
dealword("\"","界符",7,-2);
blank(p);
if(*p!='\"'){
ERROR_INFO;
return false;
}
p++;
include_bool=false;
}
else{
p++;
while(*p != '\"'){
token[i++]=*(p++);
}
++p;
token[i]='\0';
dealword(token,"STRING",4);
}
type=7;
break;
default://当不是界符的时候,
i=0;
token[i++]=*p; token[i]='\0';
++p;//2
W_OPERATOR_STRUCT* pptr=ptr;
if(findOperator(token,ptr)){//查找单运算符
token[i++]=*p; token[i]='\0';
pptr=ptr;
++p;//3
if(findOperator(token,ptr)){//查找二运算符
token[i++]=*p; token[i]='\0';
++p;//4
if( strcmp(token,">>=")==0 ){//考虑三运算符,由于只有两个,所以不用搜索了
dealword(">>=", "右移赋值", 5, 37);
type=5;
}
else if( strcmp(token,"<<=")==0){
dealword("<<=","左移赋值", 5, 38);
type=5;
}
else {//是二运算符
--p;//3
dealword(pptr->op, pptr->attribute, 5, pptr->pri);
type=5;
}
}//end_if2
else{//是一运算符
--p;//2
switch(token[0]){
case '*' :
if(type && type<4){
dealword(pptr->op, "乘", 5, pptr->pri);
}
else{
dealword(pptr->op, "指针运算", 5, pptr->pri);
}
type=5;
break;
case '-' :
if(type && type<4){
dealword(pptr->op, "减运算", 5, pptr->pri);
}
else{
dealword(pptr->op, "负运算", 5, pptr->pri);
}
type=5;
break;
case '&' :
if(type && type<4){
dealword(pptr->op, "按位与运算", 5, pptr->pri);
}
else{
dealword(pptr->op, "地址运算", 5, pptr->pri);
}
type=5;
break;
case '/' :
if(*p=='*'){
while(!(*p=='*' && *(p+1)=='/'))
{
p++;
if(!(p+1) && fin.good()){
fin.getline(line,sizeof(line));
++line_count;
p=line;
}
if(!fin.good()){
ERROR_INFO;
return false;
}
}
}
else{
dealword("/","除法运算",5,13);
}
break;
case '<' :
if(include_bool){
i=0;
++p;
blank(p);
while( isalnum(*p) || (*p=='_') || (*p=='.'))
{
token[i++]=*(p++);
}
token[i]='\0';
blank(p);
if(*p != '>'){
ERROR_INFO;
return false;
}
++p;
dealword("<","界符",7,-2);
dealword(token,"包含文件",7);
dealword(">", "界符", 7);
include_bool=false;
type=7;
}
else{
dealword(pptr->op, "指针运算", 5, pptr->pri);
type=5;
}
break;
default :
dealword(pptr->op, pptr->attribute, 5, pptr->pri);
type=5;
break;
}//end_switch
}//end_else
}//end_if1
else{
ERROR_INFO;
return false;
}
}//end_switch
}//end_else
}//end_while(p)
}//end_while(fin)
return true;
}
int iskey(char *str)//serach this word in key list
{
int i;
for(i=0; i<KEY_COUNT; i++){
if(w_key[i]==str)
break;
}
if(i<KEY_COUNT)
return i;
return -1;
}
int ismacro(char *str)//serach this word in macro list
{
int i;
for(i=0; i<MACRO_COUNT; i++){
if(w_macro[i]==str)
break;
}
if(i<MACRO_COUNT)
return i;
return -1;
}
void blank(char* &p){ //throw blank away
while(*p==' ' || *p=='\t')
p++;
}
void dealword(string str1,string str2,int flog,int k) //stor and deal a vocable
//str1 为原词,str2为属性说明,flog为类型,
//K: 当是关键字或是宏时,为其所在表中的下标
// 当是运算符时,是运算符的优先级
// 其他类型时没有意义。
{
switch(flog){
case 0 : //关键字
break;
case 1 : //标识符
break;
case 2 : //常数 number
break;
case 3 : //字母 char
break;
case 4 : //字符串常量
break;
case 5 : //运算符
break;
case 6 : //分隔符
break;
default: break;
}
cout<<setiosflags(ios_base::left)
<<setw(10)
<<str1<<", "
<<setw(3)
<<flog<<"——"
<<str2;
if(k>=0)
cout<<"——"<<k;
cout<<endl;
}
void outcode(char *str)
{
FILE *fp;
char ch='0';
fp=fopen(str,"r");
if( !fp){
cout<<"Can not open the file,Thank you!!!"<<endl;
exit(0);
}
cout<<"**************** source *******************|"<<endl;
while(fp && ch!=-1){
ch=fgetc(fp);
putchar(ch);
}
cout<<"\n********************************************|\n"<<endl;
fclose(fp);
}
void initOperator(list<W_OPERATOR_STRUCT*> &oplist)
{
FILE *fp;
bool b=true;
int pri;
char op[4],attribute[20];
W_OPERATOR_STRUCT *opstru;
fp=fopen("COperator.txt","r");
while(fp!=NULL)
{
fscanf(fp,"%s\t%d\t%s",op,&pri,attribute);
if(strcmp(op,"#")==0)
break;
opstru=new W_OPERATOR_STRUCT;
opstru->op=op;
opstru->pri=pri;
opstru->attribute=attribute;
oplist.push_back(opstru);
}
fclose(fp);
}
bool findOperator(char *op,W_OPERATOR_STRUCT* &ptr)
{
int r=0;
list<W_OPERATOR_STRUCT*>::const_iterator it;
it=oplist.begin();
while( it != oplist.end() ){
if((*it)->op==op){
ptr=*it;
return true;
}
++it;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -