插你个值
mingw opengl 环境配置笔记

编译原理实验一 PL/0语言词法分析

scturtle posted @ 2010年10月02日 23:21 in 各种实验 , 2002 阅读

代码冗长但不恶心,自我感觉良好~

有问题再改,电脑准备拿去修,贴上来备份

#include <cstdio>
#include <cstring>
#include <iostream>
#define ERROR -1
#define ID 1
#define INT 2
#define PLUS 3
#define REDUCE 4
#define MUTIL 5
#define DIV 6
#define COMMA 7
#define SEMICOLON 8
#define LPAR 9
#define RPAR 10
#define LBRACE 11
#define RBRACE 12
#define SET 14
#define BIGGER 15
#define BE 16
#define LESS 17
#define LE 18
#define EQUAL 19
#define NOTEQUAL 20
using namespace std;
char symname[30][10]={"ERROR","ID","INT","PLUS","REDUCE","MUTIL","DIV","COMMA","SEMICOLON","LPAR",
                    "RPAR","LBRACE","RBRACE","","SET","BIGGER","BE","LESS","LE","EQUAL","NOTEQUAL"};
char keywords[13][10]={"CONST","VAR","procedure","begin","end","ood","if","then","call","while","do","read","write"};
char ids[100][20];int idcnt;//变量表
char ints[100][20];int intcnt;//常数表
int sym[1000];int symcnt;int symid[1000];//符号表
bool back;//回溯标志
char ch;int pos,code,value;
char strtoken[20];

char getChar()
{
    if(back) { back=0; return ch;}
    else return getchar();
}
void retract(){back=1;}
void getbc()//跳过空白符
{
    while(ch!=EOF&&ch!='.'&&isspace(ch)) ch=getchar();
}
int reserve()//查关键字表 没有返回0
{
    for(int i=0;i<13;i++)
        if(strcmp(keywords[i],strtoken)==0) return i+30;
    return 0;
}
//插入变量表或常量表
int insertId()
{
    for(int i=0;i<idcnt;i++) if(!strcmp(ids[i],strtoken)) return i;
    strcpy(ids[idcnt],strtoken);return idcnt++;
}
int insertConst() { strcpy(ints[idcnt],strtoken);return intcnt++; }
int getsym()
{
    memset(strtoken,0,sizeof(strtoken));
    pos=0;ch=getChar();getbc();
    /////////////////////////////////
    if(isalpha(ch))
    {
        while(isalnum(ch))
            strtoken[pos++]=ch, ch=getChar();
        retract();
        code=reserve();
        if(code==0)//标识符
        {
            value=insertId();
            return ID;
        }//关键字
            return code;
    }
    /////////////////////////////////
    else if(isdigit(ch))//数字
    {
        while(isdigit(ch))
            strtoken[pos++]=ch, ch=getChar();
        retract();
        value=insertConst();
        return INT;
    }
    else//算符和界符
    {
        strtoken[pos++]=ch;
        switch(ch)
        {
            case ',':return COMMA;
            case '+':return PLUS;
            case '-':return REDUCE;
            case '*':return MUTIL;
            case '/':return DIV;
            case ';':return SEMICOLON;
            case '(':return LPAR;
            case ')':return RPAR;
            case '{':return LBRACE;
            case '}':return RBRACE;
            case '=':return EQUAL;
            case '#':return NOTEQUAL;
            case ':':
                     ch=getchar();
                     if(ch!='=') return ERROR;
                     strtoken[pos++]=ch;return SET;
            case '>':
                     ch=getchar();
                     if(ch!='=') {retract();return BIGGER;}
                     strtoken[pos++]=ch;return BE;
            case '<':
                     ch=getchar();
                     if(ch!='=') {retract();return LESS;}
                     strtoken[pos++]=ch;return LE;
            default:return ERROR;
        }
    }
}
int main()
{
    freopen("in","r",stdin);
    //freopen("out","w",stdout);
    back=0;intcnt=0;idcnt=0;symcnt=0;
    while(1)
    {
        code=getsym();
        sym[symcnt]=code;
        if(code==ID||code==INT)
            symid[symcnt++]=value;
        else symid[symcnt++]=-1;
        ////////////////////SHOW////////////////////////
        printf("%s",strtoken);
        for(int i=0;i<3-pos/8;i++) printf("\t");
        if(code<20)
        {
            printf("%s",symname[code]);
            for(int i=0;i<3-strlen(symname[code])/8;i++) printf("\t");
        }
        else
        {
            printf("SYSYM");
        }
        if(code==ID||code==INT) printf("%d\n",value);
        else puts("");
        if(ch==EOF||ch=='.') break;
    }
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter