⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 masmber_c1.cpp

📁 MCS51单片机的宏汇编器源程序。有需要的朋友请下载!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
               if(*++behind) { ++p; ++behind; return (*p); } // endif
               else { return EOLineKen; } // end else

    case '&' : EatReturn(txtCATtxt)
    case '\0': return EOLineKen;    // 如果是行末(*p=='\0'),结束
    case ';' : EatReturn(CommentKn) // 是注释, 把behind移到行尾,再返回.

    case '>' : if( *++behind == '=' ) EatReturn(GRtEQUKen)   // >=
               else { return *p; }                           // >
    case '<' : switch(*++behind)
               { case '=' : EatReturn(LessEQUKn)             // <=
                 case '>' : EatReturn(NotEqual)              // <>
                 default  :
                  { if(!PureText) { return *p; }             // <
                    MatchTnCh(behind, '>', ParaMissRtErr)
                    word.Loadstr(p+1, behind - p -2);
                    return LRstringKn;                       // <List>
                  } // end default
               } // end switch
    case '/' : if( *++behind == '*' ) EatReturn(CommBegin)   // 是注释
               else { return *p; }                           // 除号
    case '*' : if( *++behind == '/' ) EatReturn(CommEnd)     // 注释完
               else { return *p; }                           // 乘号
    case '\'': { MatchTnCh(behind, '\'', SingleQuoteErr)     // 宏调用
                 int16u len = behind -p -2;
                 if(len)
                  { word.Loadstr(p+1, len); // 把两边的单引号去掉
                    if(len == 1) { return CharDatan; } // endif
                    else { return LongCharn; }       // 'ABCDEFG'
                  } // end if(len)
                 // len == 0
                 else { word = "\"\""; return StrDataKn; } // end else
               } // end case '\''
    case '"' : { MatchTnCh(behind, '\"', DoubleQuoteErr)     // 宏调用
                 word.Loadstr(p, behind - p);
                 return StrDataKn;    // "ABCDEFG" , 因为存在"", 所以双引号不去掉.
               } // end case '"'
    default  : EatReturn(UndefSym)
  } // end switch
} // end GetNumWord
//---------------------------------------------------------------------------
#undef MatchTnCh
#undef EatReturn
#undef LtnReturn
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
#define NumWord_InMacro_Do();                                                   \
              word.ToUp();                                                      \
                   if(    word == "MACRO"                                       \
                       || word == "REPT"                                        \
                       || word == "IRP"                                         \
                       || word == "IRPC"  )                                     \
                    { if(++MacroDefNest < 0)                                    \
                       { OutputErr(MroDefNestOutErr); exit(0); }                \
                      Ln->AddTokenfield(WordSToken, word, 0);                   \
                    }                                                           \
              else if(word == "ENDM")                                           \
                    { if(--MacroDefNest > 0)                                    \
                       { Ln->AddTokenfield(WordSToken, word, 0); }              \
                      else { Ln->AddTokenfield(ENDMTkn, NULL, 0);               \
                             Ln->HeadToken() = ENDMTkn;                         \
                           }                                                    \
                    }                                                           \
              else  { Ln->AddTokenfield(WordSToken, word, 0); }
//---------------------------------------------------------------------------
#define SymWord_InMacro_Do();                                                   \
              char buf[2] = " ";                                                \
              switch(token)                                                     \
              { case txtCATtxt: { *buf = '&'; word = buf; break; }              \
                case GRtEQUKen: { word = ">="; break; }                         \
                case LessEQUKn: { word = "<="; break; }                         \
                case NotEqual : { word = "<>"; break; }                         \
                case CharDatan: case LongCharn:                                 \
                                { word = "\'"+word+"\'"; break; }               \
                case StrDataKn: break;                                          \
                default :       { *buf = (int8u)token; word = buf; }            \
              }                                                                 \
              Ln->AddTokenfield(token, word, 0);
//---------------------------------------------------------------------------
// 把字串转换成Token序列形式, 写到Ln中去。
// s 不能为NULL, 否则程序崩溃。
// 成功返回0;有error,返回1。 遇到end指令, 返回2.
//---------------------------------------------------------------------------
ERR MacroAsmber::StrToToken(char* s, bool &CommentEnable)
{ int16u len; char* behind; const char* aNumWord; ERR err;
  PureText = false;      // 对每一行来说,开始时它总是false。

  while( *s ) //  <==> while( *s != '\0' )
   { aNumWord = GetNumWord(s, len, behind); // 到字串s里找一个数字或单词。
     s = behind;    // 移动s指针使它指向下一个可见符或者行末
     // 如果是单词和数开头,返回一个指向串中第一个单词和数的指针。
     // len返回单词长度, behind指向单词后一个字符。
     // 不是单词和数开头,则返回NULL。len=0,behind指向文本行中的第一个可见符或者行末。
     if( aNumWord )   // if( aNumWord != NULL )
     // Now, 得到了一个单词和数
      { if(CommentEnable) { continue; } // endif
        // AsmFile 中的CommentEnable 未被激活(==false).
        Jstring word(aNumWord,len); // 把单词创建到word
        if(MacroDefNest > 0)
         { NumWord_InMacro_Do(); continue; } // endif   continue while
        err = NumWordToToken(word);  // 把word转化为Token。
        if( err ) { return Have_Errs; } // endif  // Have_Errs

        if( Ln->tail->Token == END ) { return 2; } // 从 while 循环中退出.
      } // endif aNumWord
     else             // ( aNumWord == NULL )
     // Now, 是符号或行末,构造符号Token.
      { Jstring word;
        int16u token = GetSymWord(s, word, behind); s = behind;
        // 得到一个符号Token。
        switch(token)
        { case EOLineKen : { return OK_no_Err; } // 如果是行末,不作为Token结点添加。
          case CommEnd   : { CommentEnable = false; continue; } // end case
          // no default.
        } // switch
        if(CommentEnable) { continue; } // endif
        // AsmFile 中的CommentEnable 未被激活
        switch(token)
        { case CommBegin: { CommentEnable = true; continue; } // end case
               // 如果是'/*'注释,不作为Token结点添加,置CE状态。
          case CommentKn: { return OK_no_Err; } // end case
               // 如果是';'注释,不作为Token结点添加,后面的字符忽略。
          case NormalERR: { Ln->AddTokenfield(NormalERR, NULL, 0);
                            return Have_Errs; } // end case
               // 遇到词法错误,把 NormalERR作为Token结点添加,后面的字符忽略。
          // no default.
        } // end switch
        if(MacroDefNest > 0) { SymWord_InMacro_Do(); } // endif
        else { ActToken(token,word,0); } // end else // 不属于宏状态
      }  // end else
   } // end while 逐个读入,读一个单词,新建一个Token。直到字符串为行末。

  return OK_no_Err; // No error
} // end StrToToken
//---------------------------------------------------------------------------
#undef NumWord_InMacro_Do();
#undef SymWord_InMacro_Do();
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// err = 0, OK.
// err = 1, Have error.
// err = 2, 遇到了"END"指令。
// 输入需提供Ln,帮你处理AddToken。Ln带值返回。
//---------------------------------------------------------------------------
ERR MacroAsmber::StrLexToAsmline(char* text, AsmLine* &Ln, bool &CommEn)
{ ERR err = StrToToken(text, CommEn); // 把一行转换成Token流。CommEn带值返回。
  if(MacroDefNest > 0) { Ln->Enable = false; } // endif
  DebugKit(printf("\n<Lexing %2.2d>%s",Ln->LineNo,text); Debugkey;); // debug
  // even have err...
  if(Ln->TknLNotEmpty()) // 如果不是只有一个头结点的话
   { register Tokenfield* pt = Ln->head->next;
     switch(pt->Token)
     { case MacroDefkn: case REPTTkn: case IRPTkn: case IRPCTkn:
                        { ++MacroDefNest; break; } // end case
       case  ENDMTkn  : { if(MacroDefNest < 0)
                           { err = Have_Errs;
                             OutputErr(ENDMNotMatchErr);
                           } // endif
                          break;
                        } // end case
       default : // Maybe have label defination.
         { pt = pt->next;
           if(pt)
            { switch(pt->Token)
              { case REPTTkn: case IRPTkn: case IRPCTkn:
                        { ++MacroDefNest; break; } // end case
                case MacroDefkn: case  ENDMTkn:
                        { err = Have_Errs;
                          OutputErr(LabelNotAllowErr);
                          break; } // end case
                // no default
              } // end switch
            } // endif
         } // end default
     } // end switch
   } // endif
  return err;
} // end StrLexToAsmline
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 把汇编文件转化成Token流。(词法分析阶段)
// 注意, 调用前,文件要先打开(open).
// 该函数会影响Ln的值。MacroDefNest
// 流程:
// (1) 初始化。
// (2) 从磁盘文件中读入一行,把ASCII文本字串转换成汇编行。
// (3) 解释首要控制命令。
// (4) 循环。
// (5) 检查宏嵌套配对。
// (6) 自动填上END。
// (7)  收尾工作。
//---------------------------------------------------------------------------
ERR MacroAsmber::FileToToken()
{ rewind(AsmFn->FilePt);            // 从文件头开始读入
  AsmFn->CommentEnable = false;     //
  MacroDefNest = 0;                 // 宏定义嵌套置零(初始值)

  int16u linecount = 0;             // 行号从第一行开始
  ERR erra = OK_no_Err;             //
  bool cont = true;                 // 在没有遇到END之前,该值为true。

  while(!AsmFn->FileEnd() && cont)  // 把整个文件转换成Token流。
   { // ............................................
     char* textbuf = AsmFn->ReadALine(); // 从文件里读入一行文本。
     Ln = new AsmLine;                // 创建新汇编行对象
     Ln->LineNo = ++linecount;        // 给新行赋行号值
     // 把ASCII文本字串转换成汇编行。
     ERR err = StrLexToAsmline(textbuf, Ln, AsmFn->CommentEnable); // 带回err值。
     switch(err)
     { case  0 : { break; } // end case
       case  2 : { cont = false; break; } // end case
       default : { erra = Have_Errs; } // end default
     } // end switch
     // 首要控制指令, 每次分析一行,解释一行。
     if(Ln->HeadToken()== MacroCTRLn && MajorCtrlParse(Ln) ) // 判断是否$行。
      { erra = Have_Errs; } // endif

     if(Ln->TknLNotEmpty()) // 如果不是只有一个头结点的话, 汇编行加进AsmFile中。
      { AsmFn->AddAsmLine(Ln); } // endif
     else                   // 只有一个头结点的汇编行不添加到AsmFile中.
      { delete Ln; Ln = NULL; } // end else
     // ............................................
   } // end while

  // Now, the file has been transfered to AsmFile.
  if(MacroDefNest != 0)
   { erra = Have_Errs; OutputErr(ENDMNotMatchErr); } // endif

  if( cont )
   { AsmFn->AddEndLine();             // 自动填上END。
     Ln = AsmFn->Tail;
     OutWarning(FileNeedEndWarn);  // 文件需要用"END"结尾。
   } // endif

  AsmFn->Tail->HeadToken() = END;     // 打上一个标记。(源文件结尾标记。)
  AsmFn->CommentEnable = false;       // 清除注释标记
  return erra;
} // end FileToToken
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// end MAsmber_C1.cpp
//---------------------------------------------------------------------------
//               Written by JamesyFront.    ZLGmcu Dev.Co.Ltd.  2002.
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -