- 注册时间
- 2005-1-21
- 最后登录
- 1970-1-1
|
发表于 2005-11-8 15:22:00
|
显示全部楼层
这是CMake的源代码.主要负责词汇的提取
你可以调用它的CMake::get_token(),返回个CToken的类.- /////////////////////////////////////////////////////
- // Make.h
- ///////////////////////////////////////////////////
- enum token_types{DELIMITER,VARIABLE,NUMBER,COMMAND,
- STRING,QUOTE,FINISHED,NONE,ENTER}; // 标记类型集合
- #define TOKEN_MAX 80
- #define STRDELIMITER "+-*^/=;(),><" // 符号集合
- #define DIM 11 // Dim
- #define AS 12 // As
- #define INTEGER 13 // Integer
- #define PRINT 14 // Print
- class CToken
- {
- public:
- char token[TOKEN_MAX];
- int token_type;
- int tok;
- };
- class CMake
- {
- public:
- CMake(char *Prog,int Proglength);
- virtual ~CMake();
- public:
- char *prog;
- int proglength;
- int isdelim(char c); // 如果是运算符号返回1,不是则返回0
- int iswhite(char c); // 是空格返回1,不是则返回0
- int look_up(char *c); // 返回COMMAND类型,c是COMMAND字符串的指针
- CToken get_token(void); // 得到标记
- int findchar(char *str,char ch); // 从str里找到ch,返回其在str里的引索;如果str里没有ch,则返回-1
- };
- /////////////////////////////////////////////////////////////////////
-
-
- // Make.cpp: implementation of the CMake class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Make.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CMake::CMake(char *Prog,int Proglength)
- {
- proglength=Proglength;
- prog=new char[Proglength+1];
- strcpy(prog,Prog);
- }
- CMake::~CMake()
- {
-
- }
- CToken CMake::get_token(void)
- {
- register char *temp;
- CToken m_token;
- m_token.token_type=0;
- m_token.tok=0;
- temp=m_token.token;
- if(*prog=='\0')
- {
- *m_token.token='\0';
- m_token.tok=0;
- m_token.token_type=FINISHED;
- return m_token;
- }
- while(iswhite(*prog)) ++prog;
-
- if(*prog=='\r') // 如果是换行符
- {
- m_token.token[0]=*prog;
- m_token.token[1]='\0';
- m_token.token_type=ENTER;
- prog++;
- return m_token;
- }
- if( isdelim(*prog)) // 如果找得到运算符号标记
- {
- *m_token.token=*prog;
- *(m_token.token+1)='\0';
- m_token.tok=0;
- m_token.token_type=DELIMITER;
- prog++;
- return m_token; // 譬如 token[0]='+' token[1]='\0';
- }
- if(*prog=='"') // 如果是字符串
- {
- prog++;
- int i=0;
- while(*prog!='"' && *prog!='\r')
- {
- m_token.token[i]=*prog;
- i++;
- prog++;
- }
- prog++;
- m_token.token[i]='\0';
- m_token.token_type=QUOTE;
- return m_token;
- }
- if( isdigit(*prog)) // 如果找到数字标记
- {
- int i=0;
- while(isdigit(*prog) && i<TOKEN_MAX) // 小于token最长为80个字符
- {
- m_token.token[i]=*prog;
- i++;
- prog++;
- }
- m_token.token[i]='\0';
- m_token.token_type=NUMBER;
- return m_token;
- }
- if( isalpha(*prog)) // 如果是命令COMMAND或是一般标记STRING
- {
- int i=0;
- while(!isdelim(*prog) && *prog!=' ') // 不能是运算符号和空格
- {
- m_token.token[i]=*prog;
- i++;
- prog++;
- }
- m_token.token[i]='\0';
- if(look_up(m_token.token)) // 如果能查到它是命令COMMAND
- {
- m_token.token_type=COMMAND;
- m_token.tok=look_up(m_token.token);
- }
- else
- {
- m_token.token_type=STRING;
- }
- return m_token;
- }
-
- m_token.token_type=NONE;
- prog++;
- return m_token;
- }
- int CMake::iswhite(char c)
- {
- if(c==' '||c=='\t') return 1;
- else return 0;
- }
- int CMake::isdelim(char c)
- {
- if( findchar(STRDELIMITER,*prog) >= 0 || c==9 || c=='\r' || c==0)
- return 1;
- return 0;
- }
- int CMake::findchar(char *str,char ch)
- {
- int length=strlen(str);
- if(length>0)
- {
- for(int i=0;i<length;i++)
- if(str[i]==ch)
- return i;
- return -1;
- }
- else return -1;
- }
- int CMake::look_up(char *c)
- {
- if(strcmp(c,"print")==0)
- return PRINT;
- if(strcmp(c,"Integer")==0)
- return INTEGER;
- if(strcmp(c,"Dim")==0)
- return DIM;
- if(strcmp(c,"As")==0)
- return AS;
- return 0;
- }
- 这是执行代码的CExecutable封装
- //////////////////////////////////////////////////
- // CExecutable.h
- ////////////////////////////////////////////////
- class CintMember
- {
- public:
- char name[64];
- int value;
- };
- class CExecutable
- {
- public:
- CExecutable(vector <CToken> tokens);
- virtual ~CExecutable();
- void Run();
- private:
- vector <CToken> m_tokens; [url]file://装[/url]所有标记的数据库
- vector <CintMember> m_intArray; [url]file://装[/url]所有int类型的变量
- void Run_Print(int *index); [url]file://*[/url]index是重要的m_tokens里的指针
- void Run_Dim(int *index); [url]file://~~[/url]
- void Run_Assignment(int *index);// 赋值语句
- [url]file://Ai[/url]是辅助的意思,Ai_*()是辅助函数
- int Ai_GetNextValue(void* result,int type,int *index); [url]file://得[/url]到代数式的值result
- int Ai_GetVarNo(char *name,int *result,int type);//得到变量在Array中的引索result
- void get_exp(int *result,int *index);
- void level2(int *result,int *index);
- void level3(int *result,int *index);
- void level4(int *result,int *index);
- void level5(int *result,int *index);
- void level6(int *result,int *index);
- void primitive(int *result,int *index);
- void arith(char o,int *r,int *h);
- void serror(int error);
- int look_up(char *c);
- int find_var(char *var_name,void *value); // 查找变量,将变量值装在*value
- int Isvar(char *name); // 看name是否是变量,返回变量类型 0:什么都不是,1:Integer,2:string
- };
- /////////////////////////////////////////
- // Executable.cpp: implementation of the CExecutable class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Executable.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CExecutable::CExecutable(vector <CToken> tokens)
- {
- m_tokens=tokens;
- }
- CExecutable::~CExecutable()
- {
- m_intArray.clear();
- m_tokens.clear();
- }
- void CExecutable::Run(void)
- {
- for(int i=0;i<=m_tokens.size()-1;i++)//注意:i是个十分重要的读取指针
- {
- if(m_tokens.at(i).token_type==COMMAND)
- {
- switch(m_tokens.at(i).tok) [url]file://tok[/url]表示是什么命令
- {
- case PRINT: Run_Print(&i);
- break;
- case DIM: Run_Dim(&i);
- break;
- default: break;
- }
- }
- [url]file://赋[/url]值语句一定要在最后来判断,因为这样如果是if后的条件判断就可以在
- [url]file://前[/url]面的if命令中跳过
- if(*m_tokens.at(i).token=='=') [url]file://如[/url]果是赋值语句
- Run_Assignment(&i);
- }
- }
- void CExecutable::Run_Print(int *index) [url]file://*[/url]index是m_tokens里的指针
- {
- if(*index<m_tokens.size()-1) // 如果下面还有token
- {
- if(m_tokens.at((*index)+1).token_type==ENTER) [url]file://如[/url]果接下来是命令
- {
- printf("\n");
- return;
- }
- (*index)++;
- int token_type=m_tokens.at(*index).token_type;
- if(Isvar(m_tokens.at(*index).token)) [url]file://如[/url]果接下来是变量
- token_type=VARIABLE;
-
- switch(token_type)
- {
- case QUOTE: [url]file://如[/url]果是要打印字符串
- {
- printf(m_tokens.at(*index).token);
- return;
- }
- case VARIABLE: [url]file://打[/url]印代数式 type只要不是COMMAND就是可以当代数式处理
- case NUMBER:
- case DELIMITER:
- {
- int result;
- Ai_GetNextValue(&result,INTEGER,index);
- printf("%d",result);
- return;
- }
- default: printf("\n");
- return;
- }
- }
- printf("\n");
-
- }
- void CExecutable::Run_Dim(int *index) [url]file://~~[/url]
- {
- int i=*index;
- if(i<m_tokens.size()-1)//~~
- if(m_tokens.at(i+1).token_type==STRING)
- {
- if(i<m_tokens.size()-3) [url]file://如[/url]果下面还应该有 变量名,As,类型 三个tokens
- {
- CintMember member;
- if(m_tokens.at(i+2).token_type==COMMAND &&
- m_tokens.at(i+2).tok==AS) [url]file://如[/url]果接下来的token是As
- {
- if(m_tokens.at(i+3).token_type==COMMAND)//接下来是变量类型
- switch(m_tokens.at(i+3).tok) [url]file://看[/url]看是什么变量类型
- {
- case INTEGER: // 如果是Integer类型
- strcpy(member.name,m_tokens.at(i+1).token);
- member.value=0;
- m_intArray.push_back(member);
- *index+=3; // 将m_tokens里的指针跳3个
- break;
- default:
- break;
- }
- }
- }
- }
- }
- void CExecutable::Run_Assignment(int *index) [url]file://index[/url]必须指到'='的token
- {
- int var_type=Isvar(m_tokens.at(*index - 1).token);
- if(!var_type) // 如果等号前面不是个变量
- {
- serror(0);
- return;
- }
- switch(var_type)
- {
- case INTEGER:
- {
- int Var_No,value;
- if(!Ai_GetVarNo(m_tokens.at(*index-1).token,&Var_No,INTEGER))
- break;
- (*index)++;
- if(!Ai_GetNextValue(&value,INTEGER,index))
- break;
- m_intArray.at(Var_No).value=value;
- break;
- }
- default: break;
- }
- }
-
- int CExecutable::Ai_GetNextValue(void *result,int type,int *index) [url]file://index[/url]指到代数式的第一个token
- {
- switch(type)
- {
- case INTEGER: get_exp((int*)result,index);
- return 1;
- default: return 0;
- }
- }
- int CExecutable::Ai_GetVarNo(char *name,int *result,int type)
- {
- switch(type)
- {
- case INTEGER:
- {
- if(m_intArray.size()==0)
- return 0;
- for(int i=0;i<=m_intArray.size()-1;i++)
- if(!strcmp(name,m_intArray.at(i).name))
- *result=i;
- return 1;
- }
- default: return 0;
- }
- }
- void CExecutable::get_exp(int *result,int *index)
- {
- if (!*m_tokens.at(*index).token)
- {
- serror(2);
- return;
- }
- level2(result,index);
-
- }
- /* add or subtract two terms */
- void CExecutable::level2(int *result,int *index)
- {
- register char op;
- int hold;
- level3(result,index);
- while ((op = *m_tokens.at(*index).token) =='+' || op == '-')
- {
- (*index)++;
- level3(&hold,index);
- arith(op,result,&hold);
- }
- }
- /* multiply or divide two factors */
- void CExecutable::level3(int *result,int *index)
- {
- register char op;
- int hold;
- level4(result,index);
- while ((op = *m_tokens.at(*index).token) == '*' || op == '/' || op == '%')
- {
- (*index)++;
- level3(&hold,index);
- arith(op,result,&hold);
- }
- }
- /* process integer exponent */
- void CExecutable::level4(int *result,int *index)
- {
- register char op;
- int hold;
- level5(result,index);
- if ((op = *m_tokens.at(*index).token) == '^')
- {
- (*index)++;
- level5(&hold,index);
- arith(op,result,&hold);
- }
- }
-
- /* is a unary + or - */
- void CExecutable::level5(int *result,int *index)
- {
- register char op;
- op = 0;
- if ((m_tokens.at(*index).token_type==DELIMITER) &&
- *m_tokens.at(*index).token == '+' ||
- *m_tokens.at(*index).token == '-' )
- {
- op = *m_tokens.at(*index).token;
- (*index)++;
- }
- level6(result,index);
- if (op)
- if(op=='-')
- *result=-(*result);
- }
-
- /* process parenthesized expression */
- void CExecutable::level6(int *result,int *index)
- {
- if ((*m_tokens.at(*index).token == '(') && (m_tokens.at(*index).token_type == DELIMITER))
- {
- (*index)++;
- level2(result,index);
- if (*m_tokens.at(*index).token!=')')
- serror(1);
- (*index)++;
- }
- else
- primitive(result,index);
- }
- /* find value of number or variable */
- void CExecutable::primitive(int *result,int *index)
- {
- int token_type=m_tokens.at(*index).token_type;
- if(Isvar(m_tokens.at(*index).token))
- token_type=VARIABLE;
- switch (token_type) {
- case VARIABLE:
- find_var(m_tokens.at(*index).token,result);
- (*index)++;
- return;
- case NUMBER:
- *result = atoi(m_tokens.at(*index).token);
- (*index)++;
- return;
- default:
- serror(0);
- }
- }
- int CExecutable::find_var(char *var_name,void *value)
- {
- for(int i=0;i<=m_intArray.size()-1;i++)
- if(!strcmp(var_name,m_intArray.at(i).name))
- {
- int *int_value=(int *)value;
- *int_value=m_intArray.at(i).value;
- return 1;
- }
- return 0;
- }
- int CExecutable::Isvar(char *name)
- {
- if(m_intArray.size()==0)
- return 0;
- for(int i=0;i<=m_intArray.size()-1;i++)
- if(!strcmp(name,m_intArray.at(i).name))
- return INTEGER;
- return 0;
- }
- /* perform the specified arithmetic */
- void CExecutable::arith(char o,int *r,int *h)
- {
- /*register*/ int t,ex;
-
- switch (o) {
- case '-':
- *r = *r-*h;
- break;
- case '+':
- *r = *r+*h;
- break;
- case '*':
- *r = *r**h;
- break;
- case '/':
- *r = (*r)/(*h);
- break;
- case '%':
- *r = (*r)%(*h);
- break;
- case '^':
- ex = *r;
- if (*h==0) {
- *r = 1;
- break;
- }
- for (t=*h-1;t>0;--t) *r=(*r)*ex;
- break;
- }
- }
- int CExecutable::look_up(char *c)
- {
- if(strcmp(c,"print")==0)
- return PRINT;
- if(strcmp(c,"Integer")==0)
- return INTEGER;
- if(strcmp(c,"Dim")==0)
- return DIM;
- if(strcmp(c,"As")==0)
- return AS;
- return 0;
- }
- void CExecutable::serror(int error)
- {
- char *e[] = {
- "syntax error",
- "unbalanced parentheses",
- "no expression present",
- "equal sign expected",
- "not a variable",
- "label table full",
- "duplicate label",
- "undefined label",
- "THEN expected",
- "TO expected",
- "too many nested FOR loops",
- "NEXT without FOR",
- "too many nested GOSUB",
- "RETURN without GOSUB"
- };
- printf ("%s\n",e[error]);
- }
复制代码 |
|