如何得到操作符的优先级

C语言的教材中有列出各种操作符的优先级。我们编写编译器的时候可以按早教材中定义的优先级编写程序,但是也可以自己定义。通常这样的优先级用一个表格表示。

所以在编译器程序中也可以用结构体数组来定义这个优先级表( operator priority table),简称OPT

1.首先有个tokentype

typedef enum Token_Type{

  ID,NUM,EXP,/*JUDGE SYMBOL*/

  IF,ELSE,DO,WHILE,SWITCH,CASE,INT,LONG,DOUBLE,FLOAT,CHAR,BREAK,FOR,

  EQ,LS,LE,GT,GE,NE, //EQ =,LS <,LE <= ,GT >, GE >=, NE !=

  ASSIGN, //'='

  ADD,SUB,MUL,DIV,INC,DEC,MOD,//OP + , - , * , / ,++,--

  LC,RC, //  '('  ')'

  LR,RR, //  '['  ']'

  LS,RS, //  '{'  '}'

  OR,AND,NOT, // '|' '&' '!'

  SEMI,// ';'

  SHARP,//'#'

  ENDFILE,

  ERROR

 }TOKEN_TYPE;

2.然后定义优先级结构体
typedef struct Opt{
     TOKEN_TYPE op;
     int Proirity;
    }OPT;
3.然后定义一个优先级表
 OPT opt[NUM_OP]={
    {INC,1},
    {DEC,1},
    {MUL,2},
    {DIV,2},
    {MOD,2},
    {ADD,3},
    {SUB,3}
    }; //biger proirity number,lower proirity
4.写个得到优先级的函数
   int get_proirity(TOKEN_TYPE tt){
    int i;
    for(i=0;i<NUM_OP;i++){
        if(opt[i].op==tt)
        return opt[i].Proirity;
        }
    }
5。扫描函数get token
    TOKEN_TYPE GetToken(void){
    int tokenBufferIndex=0;
    char ch;
    TOKEN_TYPE tt;
    TOKEN_STATE state=INIT;
    while(state!=DONE){
        ch=getc(fps);
        switch(state){
            case INIT: if(isdigit(ch))
                          {
                              state=INNUM;
                              tokenStr[tokenBufferIndex++]=ch;
                              }
                      else if (isalpha(ch)){
                            state=INID;
                            tokenStr[tokenBufferIndex++]=ch;}
                      else if((ch==' ')||ch=='/t') state=INIT;
                      else {
                        switch(ch){
                            case '=' : ch=getc(fps);
                                        if(ch=='=') tt=EQ;
                                        else {
                                        ungetc(ch,fps);
                                        tt= ASSIGN;
                                        }
                                        break;
                            case '<' : ch=getc(fps);
                                        if(ch=='=') tt=LE;
                                        else if(ch=='>') tt=NE;
                                        else {
                                        ungetc(ch,fps);
                                        tt= LS;
                                        }
                                        break;
                            case '>' : ch=getc(fps);
                                        if(ch=='=') tt= GE;
                                        else {
                                        ungetc(ch,fps);
                                        tt= GT;
                                        }
                                        break;
                            case '|':  tt=OR;
                                       state=DONE;
                                       break;
                            case '&':  tt=AND;
                                       state=DONE;
                                       break;
                            case '!':  tt=NOT;
                                       state=DONE;
                                       break;
                            case '+': ch=getc(fps);
                                        if(ch=='+') tt= INC;
                                        else{
                                        tt= ADD;
                                        ungetc(ch,fps);
                                        }
                                        state=DONE;
                                        break;
                            case '-':  ch=getc(fps);
                                        if(ch=='-') tt= DEC;
                                        else{
                                        ungetc(ch,fps);
                                        tt=SUB;
                                        }
                                        state=DONE;
                                        break;
                            case '*':
                                       tt= MUL;
                                       state=DONE;
                                       break;
                            case '/':  state=IN_MARK;
                                       break;
                            case '/n': lineno++;
                                       break;
                            case  '#': tt=SHARP;
                                       break;
                            case ';' : tt= SEMI;
                                       state=DONE;
                                       break;
                            case '(' : tt= LC;
                                       state=DONE;
                                       break;
                            case ')' : tt= RC;
                                       state=DONE;
                                       break;
                            case '[' : tt= LR;
                                       state=DONE;
                                       break;
                            case ']' : tt= RR;
                                       state=DONE;
                                       break;
                            case '{' : tt= LS;
                                       state=DONE;
                                       break;
                            case '}' : tt= RS;
                                       state=DONE;
                                       break;
                            case EOF:
                                       tt=ENDFILE;
                                       state=DONE;
                                       break;
                            default :  break;
                            }
                      }
                      break;
            case IN_MARK:
                            if(ch=='*') state= IN_MARK_SEG;
                            else if(ch=='/') state= IN_MARK_LINE;
                            else {
                                ungetc(ch,fps);
                                tt=DIV;
                                state=DONE;
                            }
                             break;
            case IN_MARK_SEG:
                              if(ch=='*') state=IN_MARK_SEG1;
                              break;
            case IN_MARK_SEG1:
                                if(ch=='/') state=INIT;
                                break;
            case IN_MARK_LINE:
                               if(ch=='/n') state=INIT;
                               break;
            case INNUM: if(isdigit(ch))
                            tokenStr[tokenBufferIndex++]=ch;
                        else
                           { tokenStr[tokenBufferIndex]='/0';
                            state=DONE;
                            ungetc(ch,fps);
                            tt=NUM;
                            }
                             break;
            case INID: if(isalpha(ch))
                            tokenStr[tokenBufferIndex++]=ch;
                        else{
                            tokenStr[tokenBufferIndex]='/0';
                            state=DONE;
                            ungetc(ch,fps);
                            tt=ID;
                            }
                             break;
            case DONE: break;
                     }
      }
      if(tt==ID){
        fprintf(fpt,"Get ID -->%s/n",tokenStr);
       }
      else if(tt==NUM)
       fprintf(fpt,"Get NUM -->%s/n",tokenStr);
     return tt;
    }
6.编写主函数
  //main.c
/*
programed by:alex shoal
edit date:2009-7-11, Satday
revision:2
****************
*Question:How to get the priority of operator?
****************
*/
#include <stdio.h>
#include <stdlib.h>
#include "global.h"
#include "scan.h"
#include "opt.h"
FILE *fps; //* file point of source
FILE *fpt;  //* file point of target
int lineno=0;
int main(int argc, char *argv[]){
TOKEN_TYPE tp;
int j=0;
fpt=stdout;
    if (argc != 2){
        printf("Usage: %s filename/n", argv[0]);
        exit(1);
    }
    if ((fps = fopen(argv[1], "r")) == NULL){
        printf("Can't open file :%s/n", argv[1]);
        exit(1);
    }
     if ((fpt = fopen("out.txt", "w+")) == NULL){
        printf("Can't open file :out.txt /n");
        exit(1);
    }
while (((tp = GetToken()) != ENDFILE)){
    switch (tp){
    case ADD:
         j=get_proirity(tp);
         fprintf(fpt,"the proirity of OP [ADD] is %d/n",j);
         break;
    case SUB:
         j=get_proirity(tp);
         fprintf(fpt,"the proirity of OP [SUB] is %d/n",j);
         break;
    case MUL:
         j=get_proirity(tp);
         fprintf(fpt,"the proirity of OP [MUL] is %d/n",j);
         break;
    case DIV:
         j=get_proirity(tp);
         fprintf(fpt,"the proirity of OP [DIV] is %d/n",j);
         break;
    case INC:
         j=get_proirity(tp);
         fprintf(fpt,"the proirity of OP [INC] is %d/n",j);
         break;
    case DEC:
         j=get_proirity(tp);
         fprintf(fpt,"the proirity of OP [DEC] is %d/n",j);
         break;
    default:
         break;
        }
}
    fclose(fps);
  return 0;
}
7. 编译程序,得到可执行程序 比如可执行文件名为 opt.exe
8。写个输入文件,含一些操作符
    //filename: in.txt
    a + b - c * 3  / 2 + i++ - j--
9. 运行程序
   opt.ext in.txt
10。产看结果,从程序主函数中可看到,
    运行之后有个 out.txt 产生。
   打开 out.txt 可看到内容
 Get ID -->a
the proirity of OP [ADD] is 3
Get ID -->b
the proirity of OP [SUB] is 3
Get ID -->c
the proirity of OP [MUL] is 2
Get NUM -->3
the proirity of OP [DIV] is 2
Get NUM -->2
the proirity of OP [ADD] is 3
Get ID -->i
the proirity of OP [INC] is 1
the proirity of OP [SUB] is 3
Get ID -->j
the proirity of OP [DEC] is 1
由此可见函数运行基本正常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值