📄 masmber_c1.cpp
字号:
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 + -