编译原理大作业暂存

时间:2022-08-26 16:27:20
编译原理大作业暂存编译原理大作业暂存
#include"scanner.h"

typedef double(*FuncPtr)(double);
//语法树的节点
struct ExprNode                  //type of syntax tree's node
{
    enum Token_Type OpCode;       //PLUS MINUS DIV POWER FUNC CONST_ID
    union
    {
        struct{ExprNode *Left,*Right;}CaseOperator;
        struct{ExprNode *Child;FuncPtr MathFuncPtr;}CaseFunc;
        double CaseConst;
        double * CaseParmPtr;
    }Content;
};

extern void Parser(char *SrcFilePtr);//参数为字符串
parser.h
编译原理大作业暂存编译原理大作业暂存
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <SDKDDKVer.h>
#include <stdio.h>
#include <tchar.h>
enum Token_Type                    // 记号的类别
{
    ORIGIN, SCALE, ROT, IS,        // 保留字(一字一码)
    TO, STEP, DRAW,FOR, FROM,    // 保留字
    T,                    // 参数
    SEMICO, L_BRACKET, R_BRACKET, COMMA,// 分隔符
    PLUS, MINUS, MUL, DIV, POWER,        // 运算符
    FUNC,                // 函数
    CONST_ID,            // 常数
    NONTOKEN,            // 空记号(源程序结束)
    ERRTOKEN
}; 

typedef double (*MathFuncPtr)(double);//函数指针

struct Token        // 记号的数据结构
{    Token_Type  type;    // 类别
    const char     *    lexeme;    // 属性,原始输入的字符串
    double        value;    // 属性,若记号是常数则是常数的值
    double        (* FuncPtr)(double);            // 属性,若记号是函数则是函数的指针
};

static Token TokenTab[] =
{    {CONST_ID,    "PI",        3.1415926,    NULL},
    {CONST_ID,    "E",        2.71828,    NULL},
    {T,            "T",        0.0,        NULL},
    {FUNC,        "SIN",        0.0,        sin},
    {FUNC,        "COS",        0.0,        cos},
    {FUNC,        "TAN",        0.0,        tan},
    {FUNC,        "LN",        0.0,        log},
    {FUNC,        "EXP",        0.0,        exp},
    {FUNC,        "SQRT",        0.0,        sqrt},
    {ORIGIN,    "ORIGIN",    0.0,        NULL},
    {SCALE,        "SCALE",    0.0,        NULL},
    {ROT,        "ROT",        0.0,        NULL},
    {IS,        "IS",        0.0,        NULL},
    {FOR,        "FOR",        0.0,        NULL},
    {FROM,        "FROM",        0.0,        NULL},
    {TO,        "TO",        0.0,        NULL},
    {STEP,        "STEP",        0.0,        NULL},
    {DRAW,        "DRAW",        0.0,        NULL}
};

extern unsigned int LineNo;
extern int InitScanner(const char*);
extern Token GetToken(void);
extern void CloseScanner(void);
scanner.h
编译原理大作业暂存编译原理大作业暂存
#include<windows.h>
#include<wingdi.h>

#define red RGB(255,0,0)        //红色
#define black RGB(0,0,0)        //黑色

extern HDC hDC;

//----------------外部函数声明
extern void        DrawPixel(unsigned long x,unsigned long y);            //绘制一个点
extern double    GetExprValue(struct ExprNode *root);                //获得表达式的值
extern void        DrawLoop(double Start,
                         double End,
                         double Step,
                         struct ExprNode *HorPtr,
                         struct ExprNode *VerPtr);
extern void        DelExprTree(struct ExprNode *root);                    //删除一棵树
semantics.h

 

编译原理大作业暂存编译原理大作业暂存
#include "semantics.h"
#include <cmath>
#include "parser.h"

extern double Parameter,                //参数T的存储空间
       Origin_x, Origin_y,    //横、纵平移距离
       Scale_x,  Scale_y,    //横、纵比例因子
       Rot_angle;

extern HDC hDC;

void        DrawPixel(unsigned long x,unsigned long y);            //绘制一个点
double        GetExprValue(struct ExprNode *root);                //获得表达式的值
void        DrawLoop(double Start,
                         double End,
                         double Step,
                         struct ExprNode *HorPtr,
                         struct ExprNode *VerPtr);
void        DelExprTree(struct ExprNode *root);                    //删除一棵树

static void Errmsg(char *string);
static void CalcCoord(struct ExprNode *Hor_Exp,
                      struct ExprNode *Ver_Exp,
                      double &Hor_x, 
                      double &Ver_y);

//----------------出错处理
void Errmsg(char *string) { exit(1); }

//----------------计算被绘制点的坐标
static void CalcCoord(struct ExprNode *Hor_Exp,
                      struct ExprNode *Ver_Exp,
                      double &Hor_x, 
                      double &Ver_y)
{
    double HorCord, VerCord, Hor_tmp;

    //原始坐标值
    HorCord = GetExprValue(Hor_Exp);
    VerCord = GetExprValue(Ver_Exp);
    //比例变换
    HorCord *= Scale_x;
    VerCord *= Scale_y;
    //旋转变换
    Hor_tmp = HorCord * cos(Rot_angle) + VerCord * sin(Rot_angle);
    VerCord = VerCord * cos(Rot_angle) - HorCord * sin(Rot_angle);
    HorCord = Hor_tmp;
    //平移变换
    HorCord += Origin_x;
    VerCord += Origin_y;
    Hor_x = HorCord;
    Ver_y = VerCord;
}

//--------------循环绘制点坐标
void DrawLoop(double Start,
              double End,
              double Step,
              struct ExprNode *HorPtr,
              struct ExprNode *VerPtr)
{
    extern double Parameter;
    double x, y;
    for(Parameter = Start; Parameter <= End; Parameter += Step) {
        CalcCoord(HorPtr, VerPtr, x, y);
        DrawPixel((unsigned long)x, (unsigned long)y);
    }
}

//---------------计算表达式的值
double GetExprValue(struct ExprNode *root) {
    if(root == NULL)    return 0.0;
    switch(root->OpCode) {
    case PLUS : return GetExprValue(root->Content.CaseOperator.Left) + 
                    GetExprValue(root->Content.CaseOperator.Right);
    case MINUS : return GetExprValue(root->Content.CaseOperator.Left) -
                     GetExprValue(root->Content.CaseOperator.Right);
    case MUL : return GetExprValue(root->Content.CaseOperator.Left) *
                     GetExprValue(root->Content.CaseOperator.Right);
    case DIV : return GetExprValue(root->Content.CaseOperator.Left) /
                     GetExprValue(root->Content.CaseOperator.Right);
    case POWER : return pow(GetExprValue(root->Content.CaseOperator.Left), 
                     GetExprValue(root->Content.CaseOperator.Right));
    case FUNC : return (*root->Content.CaseFunc.MathFuncPtr)(GetExprValue(root->Content.CaseFunc.Child));
    case CONST_ID : return root->Content.CaseConst;
    case T : return *(root->Content.CaseParmPtr);
    default :
        return 0.0;
    }
}

//---------------删除一颗语法树
void DelExprTree(struct ExprNode *root) {
    if(root == NULL)  return;
    switch(root ->OpCode) {
    case PLUS :
    case MINUS :
    case MUL :
    case DIV :
    case POWER :
        DelExprTree(root->Content.CaseOperator.Left);
        DelExprTree(root->Content.CaseOperator.Right);
        break;
    case FUNC :
        DelExprTree(root->Content.CaseFunc.Child);
        break;
    default :
        break;
    }
    delete(root);
}

//--------------绘制一个点
void DrawPixel(unsigned long x, unsigned long y) {
    SetPixel(hDC, x, y, black);
}


    
semantics.cpp
编译原理大作业暂存编译原理大作业暂存
#include "semantics.h"
#include <stdio.h>

#define MAX_CHARS 200

extern void Parser(char *SrcFilePtr);

HDC hDC;
char SrcFilePath[MAX_CHARS];
static char Name[] = "Compiler";

static bool PrepareWindow(HINSTANCE, HINSTANCE, int);
static bool CheckSrcFile(LPSTR);
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,
                     int nCmdShow)
{
    //保存源文件路径
    strcpy(SrcFilePath, "testerror.txt");
    //初始化窗口
    if(PrepareWindow(hInstance, hPrevInstance, nCmdShow)!=true) {
        MessageBox(NULL, "窗口初始化失败 !", "错误", MB_OK);
        return 1;
    }
    //检查要分析的源程序文件
    if (!CheckSrcFile(SrcFilePath))    return 1;

    //----------------------------------------
    //   调用绘图语言解释器
    Parser(SrcFilePath);
    //----------------------------------------

    //进入窗口消息循环
    MSG Msg;
    while(GetMessage(&Msg, NULL,0, 0)) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

//--------------初始化窗口函数实现

bool PrepareWindow(HINSTANCE hInst,
                   HINSTANCE hPrevInstance,
                   int nCmdShow) {
    HWND hWnd;
    WNDCLASS W;

    memset(&W, 0, sizeof(WNDCLASS));
    W.style = CS_HREDRAW | CS_VREDRAW;
    W.lpfnWndProc = WndProc;
    W.hInstance = hInst;
    W.hCursor = LoadCursor(NULL, IDC_ARROW);
    W.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    W.lpszClassName = Name;
    RegisterClass(&W);

    hWnd = CreateWindow(Name, Name,
                        WS_OVERLAPPEDWINDOW,
                        225, 225, 740, 490, NULL, NULL,hInst,NULL);
    if(hWnd == NULL) 
        return false;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    SetCursor(LoadCursor(hInst, IDC_ARROW));

    hDC = GetDC(hWnd);
    return true;
}

//--------------------检查源程序文件是否合法函数实现
bool CheckSrcFile(LPSTR lpszCmdParam) {
    FILE *file = NULL;

    if(strlen(lpszCmdParam) == 0) {
        MessageBox(NULL,"未指定源程序文件!", "Error", MB_OK);
        return false;
    }
    if((file=fopen(lpszCmdParam, "r"))==NULL) {
        MessageBox(NULL, "打开源程序文件出错!", "错误", MB_OK);
        MessageBox(NULL, lpszCmdParam, "文件名", MB_OK);
        return false;
    }
    else fclose(file);
    return true;
}

//-------------------窗口消息处理函数实现
LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    switch(Message) {
    case WM_DESTROY :
        ReleaseDC(hWnd, hDC);
        PostQuitMessage(0);
        return 0;
    case WM_PAINT :
        PAINTSTRUCT pt;
        BeginPaint(hWnd, &pt);
        Parser(SrcFilePath);
        EndPaint(hWnd, &pt);
    default:
        return DefWindowProc(hWnd,Message,wParam, lParam);

    }
}
main.cpp
编译原理大作业暂存编译原理大作业暂存
#include "parser.h"
#include <cstdio>
#include <stdarg.h>
#include "semantics.h"
//构造语法树的目的是求表达式的值
//全是递归程序
double Parameter=0,                //参数T的存储空间
       Origin_x=0,Origin_y=0,    //横、纵平移距离
       Scale_x=1, Scale_y=1,    //横、纵比例因子
       Rot_angle=0;                //旋转角度

static Token token;


//----------------------辅助函数声明
static void FetchToken();
static void MatchToken(enum Token_Type AToken);
static void SyntaxError(int case_of);
static void ErrMsg(unsigned LineNo,const char *descrip,const char *string);
static void PrintSyntaxTree(struct ExprNode *root,int indent);//打印语法树

//-----------------------外部接口与语法树构造声明函数
void Parser(char * SrcFilePtr);
static struct ExprNode * MakeExprNode(enum Token_Type opcode,...);

//---------------------非终结符的递归子程序声明
static void Program();
static void Statement();
static void OriginStatement();
static void RotStatement();
static void ScaleStatement();
static void ForStatement();
static struct ExprNode *Expression();
static struct ExprNode *Term();
static struct ExprNode *Factor();
static struct ExprNode *Component();
static struct ExprNode *Atom();



//-----------------------辅助函数
    //通过词法分析器接口GetToken获取一个记号
static void FetchToken()
{
    token = GetToken();
    if(token.type == ERRTOKEN)
        SyntaxError(1);
}

    //匹配记号

static void MatchToken(enum Token_Type The_Token)
{
    if(token.type != The_Token)
        SyntaxError(2);
    FetchToken();
}

    //处理语法错误

static void SyntaxError(int case_of)
{
    switch(case_of)
        {
            case 1 :ErrMsg(LineNo,"错误记号",token.lexeme);break;
            case 2 :ErrMsg(LineNo,"不是预期的记号",token.lexeme);break;
        }
}

    //打印错误信息
void ErrMsg(unsigned LineNo,const char *descrip,const char *string)
{
    printf("Line No %d: %s %s!\n",LineNo,descrip,string);
    char msg[256];
    memset(msg, 0, 256);
    sprintf(msg, "Line No %d: %s %s",LineNo,descrip,string);
    MessageBox(NULL, msg, "Error!", MB_OK);
    CloseScanner();
    exit(1);
}

    //深度优先先序遍历语法树并打印

void PrintSyntaxTree(struct ExprNode *root,int indent)
{
    int temp;
    for(temp = 1;temp <= indent;temp++)printf("\t");
    switch(root->OpCode)          //打印根节点
    {
    case PLUS:      printf("%s\n","+");break;
    case MINUS:     printf("%s\n","-");break;
    case MUL:       printf("%s\n","*");break;
    case DIV:       printf("%s\n","/");break;
    case POWER:     printf("%s\n","**");break;
    case FUNC:      printf("%x\n", root->Content.CaseFunc.MathFuncPtr);break;
    case CONST_ID:  printf("%f\n",root->Content.CaseConst);break;
    case T:         printf("%s\n","T");break;
    default:        printf("Error Tree Node! \n");exit(0);
    }
    if(root->OpCode == CONST_ID || root->OpCode == T)   //叶子节点返回
        return ;
    if(root->OpCode == FUNC)         //递归打印一份孩子的节点
        PrintSyntaxTree(root->Content.CaseFunc.Child,indent+1);
    else
    {
        PrintSyntaxTree(root->Content.CaseOperator.Left,indent+1);
        PrintSyntaxTree(root->Content.CaseOperator.Right,indent+1);
    }
}

//-------------------绘图解释器的外部接口

void Parser(char *SrcFilePtr)
{
    if(!InitScanner(SrcFilePtr))
    {
        printf("Open Source File Failed!\n");
    }
    FetchToken();
    Program();
    CloseScanner();
}

//----------------生成语法树的一个节点

static struct ExprNode* MakeExprNode(enum Token_Type opcode,...)
{
    struct ExprNode *ExprPtr = new(struct ExprNode);
    ExprPtr->OpCode = opcode;           //接受记号的类别
    va_list ArgPtr;
    va_start (ArgPtr,opcode);
    switch(opcode)                      //根据记号的类别构造不同的记号
    {
    case CONST_ID:
        ExprPtr->Content.CaseConst = (double)va_arg(ArgPtr,double);
        break;
    case T:
        ExprPtr->Content.CaseParmPtr = &Parameter;
        break;
    case FUNC:
        ExprPtr->Content.CaseFunc.MathFuncPtr = (FuncPtr)va_arg(ArgPtr,FuncPtr);
        ExprPtr->Content.CaseFunc.Child = (struct ExprNode *)va_arg(ArgPtr,struct ExprNode *);
        break;
    default:
        ExprPtr->Content.CaseOperator.Left = (struct ExprNode *)va_arg(ArgPtr,struct ExprNode *);
        ExprPtr->Content.CaseOperator.Right = (struct ExprNode *)va_arg(ArgPtr,struct ExprNode *);
        break;
    }
    va_end(ArgPtr);
    return ExprPtr;
}


//-------------------非终结符的递归子程序

    //program的递归子程序

static void Program()
{    
    while(token.type != NONTOKEN)
    {
        Statement();
        MatchToken(SEMICO);
    }
}

    //statement的递归子程序

static void Statement()
{
    switch(token.type)
    {
    case ORIGIN: OriginStatement(); break;
    case SCALE: ScaleStatement();  break;
    case ROT:   RotStatement();    break;
    case FOR:   ForStatement();    break;
    default:    SyntaxError(2);
    }
}

    //originstatement的递归子程序

static void OriginStatement()
{
    struct ExprNode *tmp;                                    
    MatchToken(ORIGIN);
    MatchToken(IS);
    MatchToken(L_BRACKET);
    tmp = Expression();
    Origin_x = GetExprValue(tmp);
    DelExprTree(tmp);
    MatchToken(COMMA);
    tmp = Expression();
    Origin_y = GetExprValue(tmp);
    DelExprTree(tmp);
    MatchToken(R_BRACKET);                                
}

    //scalestatement的递归子程序

static void ScaleStatement()
{
    struct ExprNode *tmp;
    
    MatchToken(SCALE);
    MatchToken(IS);
    MatchToken(L_BRACKET);
    tmp = Expression();
    Scale_x = GetExprValue(tmp);
    DelExprTree(tmp);
    MatchToken(COMMA);
    tmp = Expression();
    Scale_y = GetExprValue(tmp);
    DelExprTree(tmp);
    MatchToken(R_BRACKET);
}

    //rotstatement的递归子程序

static void RotStatement()
{
    struct ExprNode *tmp;
    
    MatchToken(ROT);
    MatchToken(IS);
    tmp = Expression();
    Rot_angle = GetExprValue(tmp);
    DelExprTree(tmp);
}

    //forstatement的递归子程序

static void ForStatement()
{
    double Start, End, Step;
    struct ExprNode *start_ptr,*end_ptr,*step_ptr,*x_ptr,*y_ptr;   //各表达式语法树根节点指针
    
    MatchToken(FOR); 
    MatchToken(T);   
    MatchToken(FROM);
    start_ptr = Expression();        //构造参数起点表达式语法树
    Start = GetExprValue(start_ptr);
    DelExprTree(start_ptr);
    MatchToken(TO); 
    end_ptr = Expression();          //构造参数终点表达式语法树
    End = GetExprValue(end_ptr);
    DelExprTree(end_ptr);
    MatchToken(STEP); 
    step_ptr = Expression();             //构造步长表达式语法树
    Step = GetExprValue(step_ptr);
    DelExprTree(step_ptr);
    MatchToken(DRAW); 
    MatchToken(L_BRACKET);
    x_ptr = Expression();            //构造横坐标表达式语法树
    MatchToken(COMMA);
    y_ptr = Expression();            //纵坐标
    MatchToken(R_BRACKET);
    DrawLoop(Start, End, Step, x_ptr, y_ptr);
    DelExprTree(x_ptr);
    DelExprTree(y_ptr);
}

    //expression的递归子程序

static struct ExprNode * Expression()
{
    struct ExprNode *left,*right;         //左右子树节点的指针
    Token_Type token_tmp;                  //当前记号
    

    left = Term();                                   //分析左操作数且得到其语法树
    while(token.type == PLUS || token.type == MINUS)
    {
        token_tmp = token.type;
        MatchToken(token_tmp);
        right = Term();                               //分析右操作数且得到其语法树
        left = MakeExprNode(token_tmp,left,right);    //构造运算的语法树,结果为左子树
    }                           
    return left;
}

    //term的递归子程序

static struct ExprNode* Term()
{
    struct ExprNode *left,*right;
    Token_Type token_tmp;
    
    left = Factor();
    while(token.type == MUL || token.type == DIV)
    {
        token_tmp = token.type;
        MatchToken(token_tmp);
        right = Factor();
        left = MakeExprNode(token_tmp,left,right);
    }
    return left;
}

    //factor的递归子程序

static struct ExprNode* Factor()
{
    struct ExprNode *left,*right;

    if(token.type == PLUS)               //匹配一元加运算
    {   MatchToken(PLUS);
        right = Factor();               //表达式退化为仅有右操作数的表达式
    }
    else if(token.type == MINUS)        //匹配一元减运算
    {   MatchToken(MINUS);              //表达式转化为二元减运算的表达式
        right = Factor();
        left = new ExprNode;
        left->OpCode = CONST_ID;
        left->Content.CaseConst = 0.0;
        right = MakeExprNode(MINUS,left,right);

    }
    else right = Component();           //匹配非终结符Component
    return right;
}
    //component的递归子程序

static struct ExprNode* Component()
{
    struct ExprNode *left,*right;

    left = Atom();
    if(token.type == POWER)
    {   MatchToken(POWER);
        right = Component();     //递归调用Component以实现POWER的右结合
        left = MakeExprNode(POWER,left,right);
    }
    return left;
}

    //atom的递归子程序

static struct ExprNode* Atom()
{
    struct Token t = token;
    struct ExprNode *address=NULL,*tmp;

    switch (token.type)
    {
        case CONST_ID:
            MatchToken(CONST_ID);
            address = MakeExprNode(CONST_ID,t.value);
            break;
        case T:
            MatchToken(T);
            address = MakeExprNode(T);
            break;
        case FUNC:
            MatchToken(FUNC);
            MatchToken(L_BRACKET);
            tmp = Expression();
            address = MakeExprNode(FUNC,t.FuncPtr,tmp);
            MatchToken(R_BRACKET);
            break;
        case L_BRACKET:
            MatchToken(L_BRACKET);
            address = Expression();
            MatchToken(R_BRACKET);
            break;
        default:
            SyntaxError(2);
    }
    return address;
}
parser.cpp
编译原理大作业暂存编译原理大作业暂存
#include "scanner.h"
#include <cctype>

#define TOKEN_LEN 100

unsigned int LineNo;
static FILE *InFile;
static char TokenBuffer[TOKEN_LEN];

extern int InitScanner(const char *FileName) {
    LineNo = 1;
    InFile = fopen(FileName, "r");
    if(InFile != NULL)
        return 1;
    else
        return 0;
}

extern void CloseScanner(void) {
    if(InFile != NULL)
        fclose(InFile);
}

static char GetChar(void) {
    int Char = getc(InFile);
    return toupper(Char);
}

static void BackChar(char Char) {
    if(Char != EOF)
        ungetc(Char, InFile);
}

static void AddCharTokenString(char Char) {
    int TokenLength = strlen(TokenBuffer);
    if(TokenLength + 1 >= sizeof(TokenBuffer))
        return;
    TokenBuffer[TokenLength] = Char;
    TokenBuffer[TokenLength+1] = '\0';
}

static void EmptyTokenString(){
    memset(TokenBuffer, 0, TOKEN_LEN);
}
//判断是否为合法标记
static Token JudgeKeyToken(const char *IDString) {
    int loop;
    for(loop=0; loop<sizeof(TokenTab)/sizeof(TokenTab[0]); loop++) {   //遍历符号表
        if(strcmp(TokenTab[loop].lexeme, IDString)==0)
            return TokenTab[loop];
    }
    Token errortoken;
    memset(&errortoken, 0, sizeof(Token));
    errortoken.type = ERRTOKEN;
    return errortoken;
}
//只是获得一个记号
extern Token GetToken() {
    Token token;
    int Char;

    memset(&token, 0, sizeof(Token));
    EmptyTokenString();//memset(TokenBuffer)
    token.lexeme = TokenBuffer;
    for(;;) {
        Char = GetChar();
        if(Char == EOF) {
            token.type = NONTOKEN;
            return token;
        }
        if(Char == '\n')
            LineNo++;
        if(!isspace(Char))
            break;
    }//处理空格等
    AddCharTokenString(Char);
    //主要就是三个if
    if(isalpha(Char)) {
        for(;;) {
            Char = GetChar();
            if(isalnum(Char))
                AddCharTokenString(Char);
            else
                break;
        }
        BackChar(Char);
        token = JudgeKeyToken(TokenBuffer);    //返回的是一个新的token,不再是GetToken函数一开始声明的token
        token.lexeme = TokenBuffer;          
        return token;
    }
    else if(isdigit(Char)) {
        for(;;) {
            Char = GetChar();
            if(isdigit(Char))
                AddCharTokenString(Char);
            else
                break;
        }
        //处理小数
        if(Char == '.') {
            AddCharTokenString(Char);
            for(;;) {
                Char = GetChar();
                if(isdigit(Char))
                    AddCharTokenString(Char);
                else
                    break;
            }
        }//end of if(Char == '.')
        BackChar(Char);
        token.type = CONST_ID;
        token.value = atof(TokenBuffer);
        return token;
    }
    else {
        switch(Char) {
        case ';' : token.type = SEMICO;        break;
        case '(' : token.type = L_BRACKET;    break;
        case ')' : token.type = R_BRACKET;    break;
        case ',' : token.type = COMMA;        break;
        case '+' : token.type = PLUS;        break;
        case '-' ://处理注释 
            Char = GetChar();
            if(Char == '-') {
                while(Char != '\n' && Char != EOF) 
                    Char = GetChar();
                BackChar(Char);
                return GetToken();//token函数的开始都会memset的
            }
            else {
                BackChar(Char);
                token.type = MINUS;
                break;
            }
        case '/' : 
            Char = GetChar();
            if(Char == '/') {
                while(Char != '\n' && Char != EOF) 
                    Char = GetChar();
                BackChar(Char);
                return GetToken();
            }
            else {
                BackChar(Char);
                token.type = DIV;
                break;
            }
        case '*' :
            Char = GetChar();
            if(Char == '*') {
                token.type = POWER;
                AddCharTokenString(Char);
                break;
            }
            else {
                BackChar(Char);
                token.type = MUL;
                break;
            }
        default :
            token.type = ERRTOKEN;
            break;
        }//end of switch
        return token;
    }//end of else(不是字母和数字,就是符号)
    
}//end of GetToken





/*
int main()
{
    Token token;
    char fname[100];

    strcpy(fname, "test.txt");

    if (!InitScanner(fname))            // 初始化词法分析器
    {
        printf("Open Source File Error ! \n"); return 0;
    }

    printf("记号类别    字符串      常数值      函数指针\n");
    printf("____________________________________________\n");
    while (1)
    {
        token = GetToken();        // 通过词法分析器获得一个记号
        if (token.type != NONTOKEN)    // 打印记号的内容
            printf("%4d %12s %12f %12x\n",
                token.type, token.lexeme, token.value, token.FuncPtr);
        else    break;            // 源程序结束,退出循环
    };
    printf("____________________________________________\n");

    CloseScanner();        // 关闭词法分析器

    return 0;
}
*/
scanner.cpp