CGen是自己的一个最近要实现的库,能够在小范围自由度的情况下配置C89的语法的编译器生成器(期间不直接用到语法树adt)。

这几天开始投入,目前只做了一点点(等能支持80%左右的C89,再提供代码下载)。


1、词法分析器全程hash(一开始的词法分析效率是每240万个词法标记需要780ms左右,后来发现这其实是重复了1000次内部预处理的结果,如果是直接240万个词法标记一次性扫描完的话,效率估计应该在每240万个词法标记需要200ms以内的时间)。
2、语法分析器的一部分(越到后面,越发现,如果自己做的功能比C89还强大应该不难,但是要严格按照C89去实现功能所有细节,就有阻力了,因为它不是自动一条规则在起作用)
3、期间发现C/C++几乎是唯内存分配是从,你可以在不引起内存冲突的情况下做如下事情:
         a、定义一个未声明和定义的结构体类型的指针
                      struct fuckfuck * fuck2;  /* fuckfuck 从未在代码里涉及,按照vc的说法- -bnr 其实关乎一种对称美的东西. */
         b、定义一个没定义的enum类型(这一点gcc是不允许的,但是tc和vs2008的c和C++编译器是允许的)
                      enum fuckfuck fuck2;
         c、union由于在没定义类型之前无法确定内存大小,所以和enum有所不同。
 4、到后面我认为本来很容易解决的比如inc和dec等等运算符,由于涉及到更加奇妙的细节而增加了考虑的时间:
         a、左结合递增(a++)和右结合的递增(++a)除了在更新a的值的阶段有所不同外,还有不同的是(C++与C89之间的不同):
                   ++(++a); C中会报错,C++中不会报错
                   ++(a++); C中会报错,C++中也会报错 
                    对于这种对应具备提前、延迟语义的IL的生成,我之前想了几种方法,不过都会让token读取look back,后来想到一种利用临时栈的方法插入指令,可以做到线性生成关于它的IL。
5、对于优化指令,我觉得那个最好还是等全部都生成好了再搞更为妥当,匹配可优化的指令模式应该不会有很大问题。
6、为了尽量避免后期的其它bug,预先定义了很多东西。
7、目前还没开始做CGenVM,不过那个东西由于我的IL还是很简化的,不会有很大问题了。
8、写到此处,我认为,考虑到一些C语言很复杂的隐性语法内容,比如很自由的语法组合和多级函数指针、以及地址引用与解引用神马的,如果严格按照C89去实现,那么投入的时间应该比写一个按自己便捷情况设计的OO语言编译器要付出更多。


代码如下:

 

 

   1/*CGen.cpp :vgl::CGen*/
   2/*----------------------------------------------------------------------------
   3Simple v1.2
   4Developer: Zblc
   5vgl::numberSystem
   6
   7namespace:
   8CGen                           :C89中间代码编译器生成器
   9
  10
  11classes:
  12Scanner                            :词法分析器
  13Parser                          :分析器
  14(内部聚合类不一一列出)
  15
  16macros:
  17#define DEBUG_EXPECT(_mark)                    :词法不匹配报错
  18#define DEBUG_NOTIDENT(_mark)                 :未定义的词法标记
  19#define DEBUG_CGEN                 :调试信息控制
  20
  21global variable:
  22
  23
  24include:
  25iostream  :用于调试信息输出 
  26--------------------------- --------------------------------------------------*/

  27#include <iostream>
  28
  29
  30#define DEBUG_CGEN
  31
  32
  33
  34
  35namespace CGen/* C中间代码生成 */
  36{
  37
  38    typedef wchar_t VWord; 
  39    typedef unsigned char VSmallSize;
  40    typedef int VBigSize;
  41    typedef short VBool;
  42
  43
  44    enum eToken/* Token分类 */
  45    {
  46        T_LeftBrace, /* {  */
  47        T_RightBrace,/* }  */
  48        T_LeftSBrace,    /*  ( */
  49        T_RightSBrace,   /*  ) */
  50        T_LeftMBrace,    /*  [ */
  51        T_RightMBrace,   /*  ] */
  52        T_UserIdent, /*  [_\b]+[_\d\b]* */
  53        T_If,/* if */
  54        T_Else,/* else */
  55        T_Star,/* * */
  56        T_Shop,/* # */
  57        T_Include,/* include */
  58        T_Define,/* define */
  59        T_Do,/* do */
  60        T_Semicolon,/* ; */
  61        T_Comma,/* , */
  62        T_Dot,/* . */
  63        T_Arrow,/* -> */
  64        T_Minus,/* - */
  65        T_Add,/* + */
  66        T_Div,/*  /  */
  67        T_Mod,/* % */
  68        T_QMark,/* ? */
  69        T_Colon,/* : */
  70        T_BitComplement,/* ~ */
  71        T_Not,/* ! */
  72        T_NotEqu,/* != */
  73        T_Equ,/* == */
  74        T_LargeThan,/* > */
  75        T_LessThan,/* < */
  76        T_EquLargeThan,/* >= */
  77        T_EquLessThan,/* <= */
  78        T_AssiAdd,/* += */
  79        T_AssiMinus,/* -= */
  80        T_AssiMul,/* *= */
  81        T_AssiOr,/* |= */
  82        T_AssiAnd,/* &= */
  83        T_AssiExOr,/* ^= */
  84        T_AssiDiv,/*  /= */
  85        T_AssiMod,/* %= */
  86        T_Enum,/* enum */
  87        T_Struct,/* struct */
  88        T_Assi,/*  = */
  89        T_Addr,/*  & */
  90        T_LogicAnd,/*  && */
  91        T_LogicOr,/*  || */
  92        T_BitOr,/* | */
  93        T_BitExOr,/*  ^ */
  94        T_Return,/* return */
  95        T_Void,/* void */
  96        T_Float,/* float */
  97        T_Double,/* Double */
  98        T_Int,/* int */
  99        T_Unsigned,/* unsigned */
 100        T_Signed,/* signed */
 101        T_Auto,/* auto */
 102        T_Static,/* static */
 103        T_Register,/* register */
 104        T_Extern,/* extern */
 105        T_Break,/* break */
 106        T_Continue,/* continue */
 107        T_Case,/* case */
 108        T_Switch,/* Switch */
 109        T_Default,/* default */
 110        T_For,/* for */
 111        T_Volatile,/* volatile */
 112        T_Const,/* const */
 113        T_Sizeof,/* sizeof */
 114        T_Typedef,/* typedef */
 115        T_Union,/* union */
 116        T_Long,/* long */
 117        /* T_SinQuo,//' */
 118        /* T_DouQuo,//" */
 119        //T_LeftComment,
 120        //T_RightComment,
 121        T_Character,
 122        T_String,
 123        T_Integer,
 124        T_Real,
 125        T_Char,
 126        T_Inc,
 127        T_Dec,
 128        T_Connect,
 129        T_LeftBit,
 130        T_RightBit,
 131        T_AssiLeftBit,
 132        T_AssiRightBit,
 133        T_While,
 134        T_END_
 135    }
;
 136
 137
 138
 139    struct stToken
 140    {
 141        eToken e;
 142        VWord szToken[10];
 143
 144    }
;
 145
 146
 147    const VBigSize MAX_TOKEN=15000;
 148
 149
 150    static stToken stTokens[100]={
 151        {T_LeftBrace,L"{"},
 152        {T_RightBrace,L"}"},
 153        {T_LeftSBrace,L"("},   /*  ( */
 154        {T_RightSBrace,L")"},   /*  ) */
 155        {T_LeftMBrace,L"["  },  /*  [ */
 156        {T_RightMBrace,L"]"  }/*  ] */
 157        {T_UserIdent,L"\0" },/*  [_\b]+[_\d\b]* */
 158        {T_If,L"if"},/* if */
 159        {T_Else,L"else"},/* else */
 160        {T_Star,L"*"},/* * */
 161        {T_Shop,L"#"},/* # */
 162        {T_Include,L"include"},/* include */
 163        {T_Define,L"define"},/* define */
 164        {T_Do,L"do"},/* do */
 165        {T_Semicolon,L";"},/* ; */
 166        {T_Comma,L","},/* , */
 167        {T_Dot,L"."},/* . */
 168        {T_Arrow,L"->"},
 169        {T_Minus,L"-"},
 170        {T_Add,L"+"},
 171        {T_Div,L"/"},
 172        {T_Mod,L"%"},
 173        {T_QMark,L"?"},
 174        {T_Colon,L":"},
 175        {T_BitComplement,L"~"},
 176        {T_Not,L"!"},
 177        {T_NotEqu,L"!="},
 178        {T_Equ,L"=="},
 179        {T_LargeThan,L">"},/* > */
 180        {T_LessThan,L"<"},/* < */
 181        {T_EquLargeThan,L">="},/* >= */
 182        {T_EquLessThan,L"<="},/* <= */
 183        {T_AssiAdd,L"+="},/* += */
 184        {T_AssiMinus,L"-="},/* -= */
 185        {T_AssiMul,L"*="},/* *= */
 186        {T_AssiOr,L"|="},/* |= */
 187        {T_AssiAnd,L"&="},/* &= */
 188        {T_AssiExOr,L"^="},/* ^= */
 189        {T_AssiDiv,L"/="},/*  /= */
 190        {T_AssiMod,L"%="},/* %= */
 191        {T_Enum,L"enum"},/* enum */
 192        {T_Struct,L"struct"},/* struct */
 193        {T_Assi,L"="},/*  = */
 194        {T_Addr,L"&"},/*  & */
 195        {T_LogicAnd,L"&&"},/*  && */
 196        {T_LogicOr,L"||"},/*  || */
 197        {T_BitOr,L"|"},/* | */
 198        {T_BitExOr,L"^"},/*  ^ */
 199        {T_Return,L"return"},/* return */
 200        {T_Void,L"void"},/* void */
 201        {T_Float,L"float"},/* float */
 202        {T_Double,L"double"},/* Double */
 203        {T_Int,L"int"},/* int */
 204        {T_Unsigned,L"unsigned"},/* unsigned */
 205        {T_Signed,L"signed"},/* signed */
 206        {T_Auto,L"auto"},/* auto */
 207        {T_Static,L"static"},/* static */
 208        {T_Register,L"register"},/* register */
 209        {T_Extern,L"extern"},/* extern */
 210        {T_Break,L"break"},/* break */
 211        {T_Continue,L"continue"},/* continue */
 212        {T_Case,L"case"},/* case */
 213        {T_Switch,L"switch"},/* Switch */
 214        {T_Default,L"default"},/* default */
 215        {T_For,L"for"},/* for */
 216        {T_Volatile,L"volatile"},/* volatile */
 217        {T_Const,L"const"},/* const */
 218        {T_Sizeof,L"sizeof"},/* sizeof */
 219        {T_Typedef,L"typedef"},/* typedef */
 220        {T_Union,L"union"},/* union */
 221        {T_Long,L"long"},/* long */
 222        /* {T_SinQuo,L"\'"},//' */
 223        /* {T_DouQuo,L"\""},//" */
 224        /*{T_LeftComment,L"/*"},*/
 225        //{T_RightComment,L"*/"},
 226        {T_Character,L"\0"},
 227        {T_String,L"\0"},
 228        {T_Integer,L"\0"},
 229        {T_Real,L"\0"},
 230        {T_Char,L"char"},
 231        {T_Inc,L"++"},
 232        {T_Dec,L"--"},
 233        {T_Connect,L"\\"},
 234        {T_LeftBit,L"<<"},
 235        {T_RightBit,L">>"},
 236        {T_AssiLeftBit,L"<<="},
 237        {T_AssiRightBit,L">>="},
 238        {T_While,L"while"},
 239        {T_END_,L"\0"}}
;
 240
 241
 242#define DEBUG_EXPECT(_mark) {std::wcout<<L"\' "<<_mark<<L" \'"<<L" Expected.\n"; return 0;}
 243#define DEBUG_NOTIDENT(_mark) {std::wcout<<L"\' "<<_mark<<L" \'"<<L" Not Identified.\n"; return 0;}
 244#define DEBUG_ERROR(_mark) {std::wcout<<_mark<<" Error.\n"; return 0;}
 245
 246
 247        /*  */
 248        class Parser
 249        {
 250        public:
 251            class IlGen;
 252            class Scanner
 253            {
 254                friend class IlGen;
 255            private:
 256                template<typename T>
 257                int lenof(T* str,T  end)
 258                {
 259                    static T* init;
 260                    init=str;
 261                    for(;*str!=end;str++);
 262                    return str-init;
 263                }

 264
 265
 266
 267                struct stUserString /* 存储用户自定义标示符位置 */
 268                {
 269                    VWord* begin;
 270                    int len;
 271                    stUserString*& operator=(stUserString & _user)
 272                    {
 273                        begin=_user.begin;
 274                        len=_user.len;
 275                    }

 276                }
;
 277
 278
 279
 280
 281                template<typename T> /* Delta Bubble Sort */
 282                void sort(T*a,int n)
 283                {
 284                    static int delta,i;
 285                    T temp;
 286                    delta=n;
 287                    for(;delta>=1;)
 288                    {
 289                        for(i=0;i+delta<n;i++)
 290                            if(lenof(stTokens[(int)a[i]].szToken,L'\0')<lenof(stTokens[(int)a[i+delta]].szToken,L'\0'))
 291                            {
 292                                temp=a[i];
 293                                a[i]=a[i+delta];
 294                                a[i+delta]=temp;
 295                            }

 296                            if(delta==1)break;
 297                            delta=(int)(delta/1.25);
 298                    }

 299                    return;
 300                }

 301                void initHash()
 302                {
 303                    for(int j=0;j!=256;j++)
 304                        for(int i=0;i!=20;i++)
 305                            eHash[j][i]=T_END_;
 306
 307                    for(int i=0;stTokens[i].e!=T_END_;i++)
 308                    {
 309                        for(int j=0;j!=20;j++)
 310                            if(eHash[stTokens[i].szToken[0]][j]==T_END_)
 311                            {
 312                                eHash[stTokens[i].szToken[0]][j]=stTokens[i].e;
 313                                break;
 314                            }
else
 315                                continue;
 316                    }

 317
 318                    for(int j=0;j!=256;j++)
 319                        sort(eHash[j],lenof(eHash[j],T_END_));
 320
 321                }

 322
 323                int isComment(VWord* _str)
 324                {
 325                    if(_str[0]!=L'/'||_str[1]!=L'*')
 326                        return 0;
 327                    for(int i=2;_str[i]!=L'\0';++i)
 328                        if(_str[i]!=L'*'||_str[i+1]!=L'/'
 329                            continue;
 330                        else 
 331                            return i+2;
 332                    return 0;
 333
 334                }

 335                int isAlphaLine(VWord c)
 336                {
 337                    return (c<=L'Z'&&c>=L'A')||(c<=L'z'&&c>=L'a')||c==L'_';
 338                }

 339                int isNum(VWord c)
 340                {
 341                    return (c<=L'9'&&c>=L'0');
 342                }

 343                int isAlphaNumLine(VWord c)
 344                {
 345                    return (c<=L'Z'&&c>=L'A')||(c<=L'z'&&c>=L'a')||(c<=L'9'&&c>=L'0')||c==L'_';
 346                }

 347                int isUserIdent(VWord* _ident)
 348                {
 349                    if(!isAlphaLine(*_ident))
 350                        return 0;
 351                    int _len=1;
 352                    for(;isAlphaNumLine(_ident[_len]);_len++);
 353                    return _len;
 354                }

 355                int isReal(VWord* _szReal)
 356                {
 357                    int _len=0;
 358                    for(;isNum(_szReal[_len]);_len++);
 359                    if(_szReal[_len++]!=L'.')
 360                        return 0;
 361                    for(;isNum(_szReal[_len]);_len++);
 362                    return _len;
 363                }

 364                int isInteger(VWord* _szInteger)
 365                {
 366                    int _len=0;
 367                    for(;isNum(_szInteger[_len]);_len++);
 368                    return _len;
 369                }

 370
 371
 372
 373                int isPrefix(VWord* _str,eToken _e)/* 关键字前缀检测 */
 374                {
 375                    static VWord* _szBuf;
 376                    static VSmallSize i;
 377                    _szBuf=stTokens[_e].szToken;
 378
 379                    for(i=0;_szBuf[i]!=L'\0';i++)
 380                        if(_str[i]!=_szBuf[i])
 381                            return 0;
 382
 383                    if(isAlphaNumLine(_str[i-1])&&isAlphaNumLine(_str[i]))/* 区分用户标示符和关键字 */
 384                        return 0;
 385                    return i;
 386                }

 387
 388                eToken eTokenList[MAX_TOKEN];
 389
 390                VBigSize tokenNum;
 391
 392                eToken eHash[256][20];
 393
 394                int userTokenIndexList[MAX_TOKEN];
 395
 396                stUserString userIndexList[MAX_TOKEN];
 397
 398                int userIndexNum;
 399
 400
 401            public:
 402
 403
 404                Scanner():userIndexNum(0),tokenNum(0)
 405                {
 406                }

 407
 408
 409#define IDENT_MAP(A,B,C,D) {userTokenIndexList[userIndexNum]=tokenNum;\
 410    userIndexList[userIndexNum].begin=A;userIndexList[userIndexNum].len=B;\
 411    ++userIndexNum;\
 412    _szProgram+=C;\
 413    eTokenList[tokenNum]=D;\
 414    ++tokenNum;}

 415
 416
 417                Scanner*& operator =(Scanner& _s)
 418                {
 419                    for(int i=0;i!=tokenNum;i++)
 420                        eTokenList[i]=_s.eTokenList[i];
 421                    for(int i=0;i!=userIndexNum;i++)
 422                    {
 423                        userTokenIndexList[i]=_s.userTokenIndexList[i];
 424                        userIndexList[i]=_s.userIndexList[i];
 425                    }

 426
 427                }

 428
 429
 430                VBool parse(VWord* _szProgram)/* 词法分析 */
 431                {
 432#ifdef DEBUG_CGEN
 433                    std::cout<<"【词法分析】"<<std::endl;
 434
 435                    VWord* szProgram=_szProgram;
 436#endif
 437
 438                    static int step,temp,j;
 439                    tokenNum=0;
 440                    userIndexNum=0;
 441
 442                    initHash();
 443
 444                    for(;*_szProgram!=L'\0';)
 445                    {
 446                        if(*_szProgram==L'/'&&_szProgram[1]==L'*')
 447                        {
 448
 449                            if(step=isComment(_szProgram))
 450                            {
 451                                _szProgram+=step;
 452                            }
else
 453                            {
 454                                DEBUG_EXPECT(L"*/");
 455                            }

 456
 457                        }
else
 458                        {
 459                            temp=0;
 460                            {
 461
 462                                for(j=0;j!=20;j++)
 463                                {
 464                                    if(*_szProgram>255)
 465                                    {
 466                                        break;
 467                                    }

 468                                    step=isPrefix(_szProgram,eHash[*_szProgram][j]);
 469                                    if(!step&&(eHash[*_szProgram][j]!=T_END_))
 470                                        continue;
 471                                    else if(step)
 472                                    {
 473
 474                                        eTokenList[tokenNum]=eHash[*_szProgram][j];
 475                                        ++tokenNum;
 476                                        _szProgram+=step;
 477                                        temp=1;
 478                                    }

 479                                    break;
 480                                }

 481                                if(temp)
 482                                    continue;
 483
 484
 485                            }

 486                            if(*_szProgram==L' '||*_szProgram==L'\t'||*_szProgram==L'\n')
 487                            {
 488                                _szProgram+=1;
 489                            }
else if(*_szProgram==L'\'')
 490                            {
 491                                int _len=1;
 492                                for(;;_len++)
 493                                {
 494
 495                                    if(_szProgram[_len]==L'\0')
 496                                    {
 497                                        DEBUG_EXPECT(L"\'");
 498                                    }
else if(_szProgram[_len]==L'\''&&(_szProgram[_len-1]!=L'\\'||_szProgram[_len-2]==L'\\'))
 499                                    {
 500
 501                                        IDENT_MAP(&_szProgram[1],_len-1,_len+1,T_Character);
 502
 503                                        break;
 504
 505                                    }

 506
 507                                }

 508                            }
else if(*_szProgram==L'\"')
 509                            {
 510                                int _len=1;
 511                                for(;;_len++)
 512                                {
 513
 514                                    if(_szProgram[_len]==L'\0')
 515                                    {
 516                                        DEBUG_EXPECT(L"\"");
 517                                    }
else if(_szProgram[_len]==L'\"'&&(_szProgram[_len-1]!=L'\\'||_szProgram[_len-2]==L'\\'))
 518                                    {
 519
 520                                        IDENT_MAP(&_szProgram[1],_len-1,_len+1,T_String);
 521
 522                                        break;
 523
 524                                    }

 525
 526                                }

 527                            }
else if(step=isUserIdent(_szProgram))
 528                            {
 529
 530                                IDENT_MAP(_szProgram,step,step,T_UserIdent);
 531
 532
 533                            }
else if(step=isReal(_szProgram))
 534                            {
 535
 536                                IDENT_MAP(_szProgram,step,step,T_Real);
 537
 538
 539                            }
else if(step=isInteger(_szProgram))
 540                            {
 541                                IDENT_MAP(_szProgram,step,step,T_Integer);
 542
 543
 544                            }
else
 545                            {
 546
 547
 548                                DEBUG_NOTIDENT(*_szProgram);
 549                                break;
 550                            }

 551                        }

 552
 553                    }

 554
 555#ifdef DEBUG_CGEN
 556                    int t=0;
 557                    j=0;
 558                    for(int i=0;i!=tokenNum;i++)
 559                    {
 560                        std::wcout<<eTokenList[i]<<L"::"<<stTokens[eTokenList[i]].szToken<<L"::";
 561                        if(userTokenIndexList[j]==i)
 562                        {
 563                            userIndexList[j].begin[userIndexList[j].len]=L'\0';
 564                            std::wcout<<userIndexList[j].begin;
 565                            j++;
 566                        }
std::wcout<<std::endl;
 567                    }

 568
 569                    std::cout<<"Tokens数:"<<tokenNum<<std::endl;
 570#endif
 571
 572
 573                    return 1;
 574                }

 575
 576            }
;
 577            /* 中间语言生成器 */
 578            class IlGen
 579            {
 580
 581                Scanner * pSc;
 582                int iToken;
 583                int iUser;
 584                int iGoto;
 585                Scanner::stUserString * pIdent;
 586
 587            private:
 588                void EmitLn(VWord* lStr,VWord* rStr,VWord* eStr)
 589                {
 590                    std::wcout<<lStr<<rStr<<eStr<<std::endl;
 591                }

 592                void EmitLn(VWord* lStr,VWord* rStr)
 593                {
 594                    std::wcout<<lStr<<rStr<<std::endl;
 595                }

 596                void EmitLn(VWord* lStr)
 597                {
 598                    std::wcout<<lStr<<std::endl;
 599                }

 600#define SetGoto(iGoto)  {std::wcout<<L"mark["<<(iGoto)<<L"]:"<<std::endl;}
 601#define Goto(_I,iGoto) {std::wcout<<(_I)<<" mark["<<(iGoto)<<L"]"<<std::endl;}
 602#define NextGoto(iGoto) {iGoto++;}
 603
 604                int Match(eToken  _token)
 605                {
 606                    if(pSc->eTokenList[iToken++]==_token)
 607                        return 1;
 608                    else
 609                        DEBUG_EXPECT(stTokens[_token].szToken);
 610                }

 611#define Peek(_mark)  (_mark==pSc->eTokenList[iToken])
 612#define Peek2(_mark,_mark2)  (_mark==pSc->eTokenList[iToken]||_mark2==pSc->eTokenList[iToken])
 613#define Peek3(_mark,_mark2,_mark3)  (_mark==pSc->eTokenList[iToken]||_mark2==pSc->eTokenList[iToken]||_mark3==pSc->eTokenList[iToken])
 614                VWord* GetIdent()
 615                {
 616                    return pSc->userIndexList[iUser++].begin;
 617                }

 618                int isLeftUnaryOp()
 619                {
 620                    switch(pSc->eTokenList[iToken])
 621                    {
 622                    case T_Not:
 623                    case T_BitComplement:
 624                    case T_Inc:
 625                    case T_Dec:
 626                    case T_Minus:
 627                    case T_Add:
 628                    case T_Star:
 629                    case T_Addr:
 630                    case T_Sizeof:
 631                        return 1;
 632                    }

 633                    return 0;
 634                }

 635                int isCompSymOp()
 636                {
 637                    return Peek2(T_Equ,T_NotEqu);
 638                }

 639
 640                int isCompAsyOp()
 641                {
 642                    return Peek2(T_LargeThan,T_LessThan)||Peek2(T_EquLargeThan,T_EquLessThan);
 643                }

 644                int isBitShiftOp()
 645                {
 646                    return Peek2(T_LeftBit,T_RightBit);
 647                }

 648
 649                int isAddOp()
 650                {
 651                    return Peek2(T_Add,T_Minus);
 652                }

 653                int isMulOp()
 654                {
 655                    return Peek3(T_Star,T_Div,T_Mod);
 656                }

 657
 658
 659                void Factor()
 660                {
 661
 662
 663
 664                    if(Peek(T_UserIdent))
 665                    {
 666                        Match(T_UserIdent);
 667                        EmitLn(L"lea ebx, [",GetIdent(),L"]");
 668                        EmitLn(L"mov eax, dword ptr [ebx]");
 669                    }
else if(Peek(T_Integer)){
 670                        Match(T_Integer);
 671                        EmitLn(L"mov eax, ",GetIdent());
 672                    }
else if(Peek(T_LeftSBrace))
 673                    {
 674                        Match(T_LeftSBrace);
 675                        TernaryOp();
 676                        Match(T_RightSBrace);
 677                    }
else if(Peek(T_Not))
 678                    {
 679                        int _iGoto,_iGoto2;
 680
 681                        NextGoto(iGoto);
 682                        _iGoto=iGoto;
 683
 684                        NextGoto(iGoto);
 685                        _iGoto2=iGoto;
 686
 687                        Match(T_Not);
 688
 689                        TernaryOp();
 690
 691
 692                        EmitLn(L"test eax, {fh, 8}");
 693                        Goto(L"jnz",_iGoto);
 694                        EmitLn(L"mov eax, 1");
 695                        Goto(L"jmp",_iGoto2);
 696
 697                        SetGoto(_iGoto);
 698                        EmitLn(L"mov eax, 0");
 699                        SetGoto(_iGoto2);
 700                    }
else if(Peek(T_BitComplement))
 701                    {
 702                        Match(T_BitComplement);
 703
 704                        TernaryOp();
 705
 706
 707                        EmitLn(L"not eax");
 708                    }
else if(Peek(T_Add))
 709                    {
 710                        Match(T_Add);
 711
 712                        TernaryOp();
 713
 714
 715                    }
else if(Peek(T_Minus))
 716                    {
 717                        Match(T_Minus);
 718
 719                        TernaryOp();
 720
 721                        EmitLn(L"neg eax");
 722                    }
else if(Peek(T_Sizeof))
 723                    {
 724                        Match(T_Sizeof);
 725
 726                        TernaryOp();
 727
 728                        EmitLn(L"mov ecx, __atom__sizeof(eax)");
 729                        EmitLn(L"mov eax, ecx");
 730                    }

 731
 732
 733
 734
 735                    /*
 736                    -case T_Not:
 737                    -case T_BitComplement:
 738                    case T_Inc:
 739                    case T_Dec:
 740                    -case T_Minus:
 741                    -case T_Add:
 742                    case T_Star:
 743                    case T_Addr:
 744                    -case T_Sizeof:*/

 745                }

 746                void Term()
 747                {
 748                    Factor();
 749
 750                    while(isMulOp())
 751                    {
 752                        EmitLn(L"push eax");
 753                        if(Peek(T_Star))
 754                        {
 755                            Match(T_Star);
 756                            Factor();
 757
 758                            EmitLn(L"pop ebx");
 759                            EmitLn(L"mul eax, ebx");
 760                        }
else if(Peek(T_Div))
 761                        {
 762                            Match(T_Div);
 763                            Factor();
 764
 765                            EmitLn(L"pop ebx");
 766                            EmitLn(L"div eax, ebx");
 767                            EmitLn(L"xchg eax, ebx");
 768                        }
else if(Peek(T_Mod))
 769                        {
 770                            Match(T_Mod);
 771                            Factor();
 772
 773                            EmitLn(L"pop ebx");
 774                            EmitLn(L"mod eax, ebx");
 775                            EmitLn(L"xchg eax, ebx");
 776                        }

 777                    }

 778                }

 779                void Expression()
 780                {
 781
 782                    Term();
 783
 784                    while(isAddOp())
 785                    {
 786                        EmitLn(L"push eax");
 787                        if(Peek(T_Add))
 788                        {
 789                            Match(T_Add);
 790
 791                            Term();
 792                            EmitLn(L"pop ebx");
 793                            EmitLn(L"add eax, ebx");
 794                        }
else if(Peek(T_Minus))
 795                        {
 796                            Match(T_Minus);
 797
 798                            Term();
 799                            EmitLn(L"pop ebx");
 800                            EmitLn(L"sub eax, ebx");
 801                            EmitLn(L"neg eax");
 802                        }

 803                    }

 804
 805                }

 806                void BitShift()
 807                {
 808                    Expression();
 809
 810                    while(isBitShiftOp())
 811                    {
 812                        EmitLn(L"push eax");
 813                        if(Peek(T_LeftBit))
 814                        {
 815                            Match(T_LeftBit);
 816
 817                            Expression();
 818                            EmitLn(L"pop ebx");
 819                            EmitLn(L"xchg eax, ebx");
 820                            EmitLn(L"shl eax, ebx");
 821                        }
else if(Peek(T_RightBit))
 822                        {
 823                            Match(T_RightBit);
 824
 825                            Expression();
 826                            EmitLn(L"pop ebx");
 827                            EmitLn(L"xchg eax, ebx");
 828                            EmitLn(L"shr eax, ebx");
 829                        }

 830                    }

 831                }

 832                void CompAsyOp()
 833                {
 834                    BitShift();
 835
 836                    while(isCompAsyOp())
 837                    {
 838                        EmitLn(L"push eax");
 839                        if(Peek(T_LargeThan))
 840                        {
 841                            Match(T_LargeThan);
 842
 843                            BitShift();
 844                            EmitLn(L"pop ebx");
 845                            EmitLn(L"cmp eax, ebx");
 846                            EmitLn(L"mov eax, cf");
 847                            EmitLn(L"not zf");
 848                            EmitLn(L"mov eax, zf");
 849                        }
else if(Peek(T_LessThan))
 850                        {
 851                            Match(T_LessThan);
 852
 853                            BitShift();
 854                            EmitLn(L"pop ebx");
 855                            EmitLn(L"cmp eax, ebx");
 856                            EmitLn(L"not cf");
 857                            EmitLn(L"mov eax, cf");
 858                            EmitLn(L"not zf");
 859                            EmitLn(L"mov eax, zf");
 860                        }
else if(Peek(T_EquLargeThan))
 861                        {
 862                            Match(T_EquLargeThan);
 863
 864                            BitShift();
 865                            EmitLn(L"pop ebx");
 866                            EmitLn(L"cmp eax, ebx");
 867                            EmitLn(L"mov eax, cf");
 868                            EmitLn(L"mov eax, zf");
 869                        }
else if(Peek(T_EquLessThan))
 870                        {
 871                            Match(T_EquLessThan);
 872
 873                            BitShift();
 874                            EmitLn(L"pop ebx");
 875                            EmitLn(L"cmp eax, ebx");
 876                            EmitLn(L"not cf");
 877                            EmitLn(L"mov eax, cf");
 878                            EmitLn(L"mov eax, zf");
 879                        }

 880                    }

 881                }

 882                void CompSymOp()
 883                {
 884                    CompAsyOp();
 885
 886                    while(isCompSymOp())
 887                    {
 888
 889                        EmitLn(L"push eax");
 890                        if(Peek(T_NotEqu))
 891                        {
 892                            Match(T_NotEqu);
 893
 894                            CompAsyOp();
 895                            EmitLn(L"pop ebx");
 896                            EmitLn(L"cmp eax, ebx");
 897                            EmitLn(L"not zf");
 898                            EmitLn(L"mov eax, zf");
 899                        }
else if(Peek(T_Equ))
 900                        {
 901                            Match(T_Equ);
 902
 903                            CompAsyOp();
 904                            EmitLn(L"pop ebx");
 905                            EmitLn(L"cmp eax, ebx");
 906                            EmitLn(L"mov eax, zf");
 907                        }

 908                    }

 909                }

 910                void BitAnd()
 911                {
 912                    CompSymOp();
 913
 914                    while(Peek(T_Addr))
 915                    {
 916
 917                        EmitLn(L"push eax");
 918
 919                        Match(T_Addr);
 920                        CompSymOp();
 921                        EmitLn(L"pop ebx");
 922                        EmitLn(L"and eax, ebx");
 923
 924                    }

 925                }

 926                void BitXor()
 927                {
 928                    BitAnd();
 929
 930                    while(Peek(T_BitExOr))
 931                    {
 932
 933                        EmitLn(L"push eax");
 934
 935                        Match(T_BitExOr);
 936                        BitAnd();
 937                        EmitLn(L"pop ebx");
 938                        EmitLn(L"xor eax, ebx");
 939
 940                    }

 941                }

 942                void BitOr()
 943                {
 944                    BitXor();
 945
 946                    while(Peek(T_BitOr))
 947                    {
 948
 949                        EmitLn(L"push eax");
 950
 951                        Match(T_BitOr);
 952                        BitXor();
 953                        EmitLn(L"pop ebx");
 954                        EmitLn(L"or eax, ebx");
 955
 956                    }

 957                }

 958                void LogicAnd()
 959                {
 960                    int _iGoto=0,_iGoto2=0;
 961
 962                    BitOr();
 963
 964                    if(Peek(T_LogicAnd))
 965                    {
 966
 967                        NextGoto(iGoto);/* 当iGoto被赋予前,更新iGoto */
 968                        _iGoto=iGoto;
 969
 970                        NextGoto(iGoto);
 971                        _iGoto2=iGoto;
 972
 973                        EmitLn(L"test eax, {fh: 8}");
 974                        Goto(L"jz",_iGoto);
 975                        while(Peek(T_LogicAnd))
 976                        {
 977                            Match(T_LogicAnd);
 978                            BitOr();
 979                            EmitLn(L"test eax, {fh: 8}");
 980                            Goto(L"jz",_iGoto);
 981
 982                            if(!Peek(T_LogicAnd))
 983                            {
 984                                EmitLn(L"mov eax, 1");
 985                                Goto(L"jmp",_iGoto2);
 986                            }

 987                        }

 988                        SetGoto(_iGoto);
 989                        EmitLn(L"mov eax, 0");
 990                        SetGoto(_iGoto2);
 991
 992                    }

 993
 994
 995                }

 996                void LogicOr()
 997                {
 998                    LogicAnd();
 999
1000                    if(Peek(T_LogicOr))
1001                    {
1002
1003                        int _iGoto,_iGoto2;
1004
1005                        NextGoto(iGoto);/* 当iGoto被赋予前,更新iGoto */
1006                        _iGoto=iGoto;
1007
1008                        NextGoto(iGoto);
1009                        _iGoto2=iGoto;
1010
1011                        EmitLn(L"test eax, {fh: 8}");
1012                        Goto(L"jnz",_iGoto);
1013                        while(Peek(T_LogicOr))
1014                        {
1015                            Match(T_LogicOr);
1016                            LogicAnd();
1017                            EmitLn(L"test eax, {fh: 8}");
1018                            Goto(L"jnz",_iGoto);
1019
1020                            if(!Peek(T_LogicOr))
1021                            {
1022                                EmitLn(L"mov eax, 0");
1023                                Goto(L"jmp",_iGoto2);
1024                            }

1025                        }

1026                        SetGoto(_iGoto);
1027                        EmitLn(L"mov eax, 1");
1028                        SetGoto(_iGoto2);
1029
1030                    }

1031
1032
1033                }

1034                void TernaryOp()
1035                {
1036
1037                    LogicOr();
1038                    if(Peek(T_QMark))
1039                    {
1040                        int _iGoto,_iGoto2;/* 跳转标记 */
1041
1042                        Match(T_QMark);
1043
1044                        EmitLn(L"test eax, {fh: 8}");/* 三目运算符条件检测 */
1045
1046                        NextGoto(iGoto);
1047                        _iGoto=iGoto;
1048
1049                        Goto(L"jz",_iGoto);/* 当表达式为假 */
1050
1051
1052                        TernaryOp();
1053
1054                        NextGoto(iGoto);
1055                        _iGoto2=iGoto;
1056
1057                        Goto(L"jmp",_iGoto2);
1058
1059
1060                        Match(T_Colon);
1061
1062                        SetGoto(_iGoto);
1063                        TernaryOp();
1064
1065                        SetGoto(_iGoto2);
1066
1067                    }

1068
1069
1070                }

1071                void Assignment()
1072                {
1073
1074
1075                    Match(T_UserIdent);
1076
1077                    VWord* pName=GetIdent();
1078
1079                    Match(T_Assi);
1080                    TernaryOp();
1081
1082
1083                    EmitLn(L"lea ebx, ",pName);
1084                    EmitLn(L"mov [ebx], eax");
1085
1086                }

1087                void IfStatement()
1088                {
1089                    int _iGoto=0,_iGotoEnd=0,_tag=0;
1090                    Match(T_If);/* if(<expression>) */
1091                    Match(T_LeftSBrace);
1092                    TernaryOp();
1093                    Match(T_RightSBrace);
1094
1095                    NextGoto(iGoto);
1096                    _iGoto=iGoto;
1097                    NextGoto(iGoto);
1098                    _iGotoEnd=iGoto;
1099
1100                    EmitLn(L"test eax, {fh, 8}");
1101                    Goto(L"jz",_iGoto);
1102
1103
1104                    if(Peek(T_LeftBrace))
1105                    {
1106                        Match(T_LeftBrace);/* {<statement>*} */
1107                        if(!Peek(T_RightBrace))
1108                        {
1109                            do{
1110                                Statement();
1111                            }
while(!Peek(T_RightBrace));
1112                            Match(T_RightBrace);
1113                        }
else
1114                        {
1115                            Match(T_RightBrace);
1116                        }

1117                    }
else
1118                    {
1119                        Statement();
1120                    }

1121
1122
1123                    Goto(L"jmp",_iGotoEnd);
1124
1125                    while(Peek(T_Else))
1126                    {            
1127                        _tag=1;
1128                        Match(T_Else);
1129                        if(Peek(T_If))
1130                        {
1131                            SetGoto(_iGoto);
1132                            Match(T_If);/* else if(<expression>) */
1133                            Match(T_LeftSBrace);
1134                            TernaryOp();
1135                            Match(T_RightSBrace);
1136
1137                            NextGoto(iGoto);
1138                            _iGoto=iGoto;
1139
1140                            EmitLn(L"test eax, {fh, 8}");
1141                            Goto(L"jz",_iGoto);
1142
1143
1144                            if(Peek(T_LeftBrace))
1145                            {
1146                                Match(T_LeftBrace);/* {<statement>*} */
1147                                if(!Peek(T_RightBrace))
1148                                {
1149                                    do{
1150                                        Statement();
1151                                    }
while(!Peek(T_RightBrace));
1152                                    Match(T_RightBrace);
1153                                }
else
1154                                {
1155                                    Match(T_RightBrace);
1156                                }

1157                            }
else
1158                            {
1159                                Statement();
1160                            }

1161                            Goto(L"jmp",_iGotoEnd);
1162
1163                        }
else
1164                        {
1165                            SetGoto(_iGoto);
1166                            if(Peek(T_LeftBrace))
1167                            {
1168
1169                                Match(T_LeftBrace);/* {<statement>*} */
1170                                if(!Peek(T_RightBrace))
1171                                {
1172                                    do{
1173                                        Statement();
1174                                    }
while(!Peek(T_RightBrace));
1175                                    Match(T_RightBrace);
1176                                }
else
1177                                {
1178                                    Match(T_RightBrace);
1179                                }

1180                            }
else
1181                            {
1182                                Statement();
1183                            }

1184                            break;
1185                        }

1186                    }

1187                    if(_tag==0)
1188                    {
1189                        SetGoto(_iGoto);
1190                    }

1191
1192                    SetGoto(_iGotoEnd);
1193                }

1194                void WhileStatement()
1195                {
1196                    int _iGoto=0,_iGotoEnd=0;
1197                    Match(T_While);
1198
1199                    NextGoto(iGoto);
1200                    _iGoto=iGoto;
1201
1202                    NextGoto(iGoto);
1203                    _iGotoEnd=iGoto;
1204
1205
1206
1207                    SetGoto(_iGoto);
1208
1209
1210                    Match(T_LeftSBrace);
1211                    TernaryOp();
1212                    Match(T_RightSBrace);
1213                    EmitLn(L"test eax, {fh, 8}");
1214                    Goto(L"jz",_iGotoEnd);
1215
1216
1217                    if(Peek(T_LeftBrace))
1218                    {
1219
1220                        Match(T_LeftBrace);/* {<statement>*} */
1221                        if(!Peek(T_RightBrace))
1222                        {
1223                            do{
1224                                Statement();
1225                            }
while(!Peek(T_RightBrace));
1226                            Match(T_RightBrace);
1227                        }
else
1228                        {
1229                            Match(T_RightBrace);
1230                        }

1231                    }
else
1232                    {
1233                        Statement();
1234                    }

1235
1236
1237                    Goto(L"jmp",_iGoto);
1238                    SetGoto(_iGotoEnd);
1239                }

1240                void DoWhileStatement()
1241                {
1242                    int _iGoto=0,_iGotoEnd=0;
1243                    Match(T_Do);
1244
1245                    NextGoto(iGoto);
1246                    _iGoto=iGoto;
1247
1248                    NextGoto(iGoto);
1249                    _iGotoEnd=iGoto;
1250
1251                    SetGoto(_iGoto);
1252
1253                    if(Peek(T_LeftBrace))
1254                    {
1255                        Match(T_LeftBrace);/* {<statement>*} */
1256                        if(!Peek(T_RightBrace))
1257                        {
1258                            do{
1259                                Statement();
1260                            }
while(!Peek(T_RightBrace));
1261                            Match(T_RightBrace);
1262                        }
else
1263                        {
1264                            Match(T_RightBrace);
1265                        }

1266                    }
else
1267                    {
1268                        Statement();
1269                    }

1270
1271                    Match(T_While);
1272                    Match(T_LeftSBrace);
1273                    TernaryOp();
1274                    Match(T_RightSBrace);
1275                    EmitLn(L"test eax, {fh, 8}");
1276                    Goto(L"jz",_iGotoEnd);
1277
1278                    Goto(L"jmp",_iGoto);
1279                    SetGoto(_iGotoEnd);
1280                }

1281                void ForStatement()
1282                {
1283                    int _iGoto=0,_iGotoEnd=0,_iGoto2=0,_iGoto3;
1284                    NextGoto(iGoto);
1285                    _iGoto=iGoto;
1286
1287                    NextGoto(iGoto);
1288                    _iGotoEnd=iGoto;
1289
1290                    NextGoto(iGoto);
1291                    _iGoto2=iGoto;
1292
1293                    NextGoto(iGoto);
1294                    _iGoto3=iGoto;
1295
1296                    Match(T_For);
1297                    Match(T_LeftSBrace);
1298                    TernaryOp();/* init for */
1299                    Match(T_Semicolon);
1300
1301
1302                    TernaryOp();/* infer-expression */
1303                    Match(T_Semicolon);
1304
1305                    SetGoto(_iGoto3);
1306                    EmitLn(L"test eax, {fh, 8}");
1307                    Goto(L"jz",_iGotoEnd);
1308                    Goto(L"jmp",_iGoto2);
1309
1310                    SetGoto(_iGoto);
1311                    TernaryOp();/* rear-set-expression */
1312                    Match(T_RightSBrace);
1313                    Goto(L"jmp",_iGoto3);
1314
1315                    SetGoto(_iGoto2);
1316
1317                    if(Peek(T_LeftBrace))
1318                    {
1319
1320                        Match(T_LeftBrace);/* {<statement>*} */
1321                        if(!Peek(T_RightBrace))
1322                        {
1323                            do{
1324                                Statement();
1325                            }
while(!Peek(T_RightBrace));
1326                            Match(T_RightBrace);
1327                        }
else
1328                        {
1329                            Match(T_RightBrace);
1330                        }

1331                    }
else
1332                    {
1333                        Statement();
1334                    }

1335
1336                    Goto(L"jmp",_iGoto2);
1337                    SetGoto(_iGotoEnd);
1338                }

1339                void SemicolonStatement()
1340                {
1341
1342                }

1343                void Statement()
1344                {
1345                    if(Peek(T_LeftBrace))
1346                    {
1347
1348                        Match(T_LeftBrace);
1349                        if(!Peek(T_RightBrace))
1350                        {
1351                            do{
1352                            Statement();
1353                            }
while(!Peek(T_RightBrace));
1354                            Match(T_RightBrace);
1355                        }
else
1356                        {
1357                            Match(T_RightBrace);
1358                        }

1359                        
1360
1361                    }
else if(Peek(T_If))
1362                    {
1363                        IfStatement();
1364                        
1365
1366                    }
else if(Peek(T_While))
1367                    {
1368                        WhileStatement();
1369                        
1370
1371                    }
else if(Peek(T_Do))
1372                    {
1373                        DoWhileStatement();
1374                        
1375
1376                    }
else if(Peek(T_For))
1377                    {
1378                        ForStatement();
1379                        
1380
1381                    }
else
1382                    {
1383                        TernaryOp();
1384                        Match(T_Semicolon);
1385                        
1386                    }

1387
1388                }

1389
1390                void Program()
1391                {
1392                    while(iToken<pSc->tokenNum)
1393                    {
1394                          Statement();
1395                    }

1396                }

1397                void Init()
1398                {
1399                    iToken=0;/* Token当前位置 */
1400                    iUser=0;/* 用户自定义标示符当前指向 */
1401                    iGoto=0;/* 跳转标志产生序号 */
1402                }

1403            public:
1404                IlGen()
1405                {
1406                }

1407
1408                int parse(Scanner * _pSc)
1409                {
1410#ifdef DEBUG_CGEN
1411                    std::cout<<"【中间代码生成】"<<std::endl;
1412#endif
1413                    pSc=_pSc;/* 词法分析器初始化 */
1414                    Init();
1415                    Program();
1416
1417                    return 1;
1418
1419                }

1420            }
;
1421        private:
1422            Scanner scanner;
1423            IlGen ils;
1424        public:
1425            Parser()
1426            {
1427            }

1428            int parse(VWord* _text)
1429            {
1430
1431                if(!scanner.parse(_text))
1432                    DEBUG_ERROR(L"Scanning");
1433                if(!ils.parse(&scanner))
1434                    DEBUG_ERROR(L"Interlingua");
1435
1436
1437
1438                return 1;
1439
1440            }

1441        }
;
1442        void input(VWord* _list,VWord end)
1443        {
1444            setlocale(LC_ALL, "");
1445            int i=0;
1446            for(;(_list[i]=std::wcin.get())!=end;i++);
1447            _list[i]=L'\0';
1448
1449        }

1450
1451};
1452




 1#include <iostream>
 2#include "CGen.h"
 3
 4#include <string>
 5#include <locale>
 6
 7
 8#include "runtime.h"
 9using namespace std;
10
11
12int main()
13{
14    CGen::Parser parser;
15
16    os::runtime rt;
17    
18
19    const CGen::VBigSize MAX_CODE=CGen::MAX_TOKEN*5;
20
21    CGen::VWord list[MAX_CODE];
22    CGen::input(list,L'$');
23
24
25
26    //rt.begin();
27    //for(int i=0;i!=1000;i++)
28
29    parser.parse(list);
30    
31    //rt.end();
32    //cout<<"处理"<<2456*1000/10000.0<<"万个词法标记所用的时间:"<<rt.getDTime()<<"ms"<<endl;
33    return 0;
34}



 

  1先给出一个运行的case(片段代码的IL生成):
  2
  3if(1>2+(5+1)/(3-2*5/(3123213))&2)
  4{  for(1;a!=10;135){ a>50?a:b>10?1:2;}
  5}
$
  6【词法分析】
  77::if::
  82::(::
  973::::1
 1028::>::
 1173::::2
 1219::+::
 132::(::
 1473::::5
 1519::+::
 1673::::1
 173::)::
 1820::/::
 192::(::
 2073::::3
 2118::-::
 2273::::2
 239::*::
 2473::::5
 2520::/::
 262::(::
 2773::::3123213
 283::)::
 293::)::
 3043::&::
 3173::::2
 323::)::
 330::{::
 3464::for::
 352::(::
 3673::::1
 3714::;::
 386::::a
 3926::!=::
 4073::::10
 4114::;::
 4273::::135
 433::)::
 440::{::
 456::::a
 4628::>::
 4773::::50
 4822::?::
 496::::a
 5023:::::
 516::::b
 5228::>::
 5373::::10
 5422::?::
 5573::::1
 5623:::::
 5773::::2
 5814::;::
 591::}
::
 601::}
::
 61Tokens数:54
 62【中间代码生成】
 63mov eax, 1
 64push eax
 65mov eax, 2
 66push eax
 67mov eax, 5
 68push eax
 69mov eax, 1
 70pop ebx
 71add eax, ebx
 72push eax
 73mov eax, 3
 74push eax
 75mov eax, 2
 76push eax
 77mov eax, 5
 78pop ebx
 79mul eax, ebx
 80push eax
 81mov eax, 3123213
 82pop ebx
 83div eax, ebx
 84xchg eax, ebx
 85pop ebx
 86sub eax, ebx
 87neg eax
 88pop ebx
 89div eax, ebx
 90xchg eax, ebx
 91pop ebx
 92add eax, ebx
 93pop ebx
 94cmp eax, ebx
 95mov eax, cf
 96not zf
 97mov eax, zf
 98push eax
 99mov eax, 2
100pop ebx
101and eax, ebx
102test eax, {fh, 8}
103jz mark[1]
104mov eax, 1
105lea ebx, [a]
106mov eax, dword ptr [ebx]
107push eax
108mov eax, 10
109pop ebx
110cmp eax, ebx
111not zf
112mov eax, zf
113mark[6]:
114test eax, {fh, 8}
115jz mark[4]
116jmp mark[5]
117mark[3]:
118mov eax, 135
119jmp mark[6]
120mark[5]:
121lea ebx, [a]
122mov eax, dword ptr [ebx]
123push eax
124mov eax, 50
125pop ebx
126cmp eax, ebx
127mov eax, cf
128not zf
129mov eax, zf
130test eax, {fh: 8}
131jz mark[7]
132lea ebx, [a]
133mov eax, dword ptr [ebx]
134jmp mark[8]
135mark[7]:
136lea ebx, [b]
137mov eax, dword ptr [ebx]
138push eax
139mov eax, 10
140pop ebx
141cmp eax, ebx
142mov eax, cf
143not zf
144mov eax, zf
145test eax, {fh: 8}
146jz mark[9]
147mov eax, 1
148jmp mark[10]
149mark[9]:
150mov eax, 2
151mark[10]:
152mark[8]:
153jmp mark[5]
154mark[4]:
155jmp mark[2]
156mark[1]:
157mark[2]: