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

📄 casl.y.bak

📁 这是一个软件水平资格考试中使用的CASL汇编语言的编译器,实现文件中包括一个编译器,一个虚拟机,一个类似于Debug的调试器.
💻 BAK
📖 第 1 页 / 共 3 页
字号:
%{
#include <math.h>
#include <malloc.h>
#include <stdlib.h>
#include <algorithm>

#include "../../Compiler/GlobalVariableDef.h"
int yyerror(char *s);
int yylex(void);
%}
%token DECIMAL
%token HEX
%token ID
%token STR
%token LABEL
%token DS
%token DC
%token GR0
%token GR1
%token GR2
%token GR3
%token GR4
%token LD
%token ST
%token LEA
%token ADD
%token SUB
%token AND
%token OR
%token EOR
%token CPA
%token CPL
%token SLA
%token SRA
%token SLL
%token SRL
%token JMP
%token JPZ
%token JMI
%token JNZ
%token JZE
%token PUSH
%token POP
%token CALL
%token RET
%token START
%token END
%token IN
%token OUT
%token EXIT
%%
PROGRAM:  START BODY END {printf("Input Ok!\n");};

BODY: DEFPART EXECPART;

DEFPART: DEFPART  DEFDETAIL | ;

DEFDETAIL: DSDEF | DCDEF;

DSDEF: LBLSTMT  DS  DECIMAL  
                            {
                                g_vecVariable.push_back(CaslVariable((char*)$1, $3));
                                free((char*)$1);
                            }
	;  

DCDEF: LBLSTMT  DC  CONST   
                         {
		                    strcpy(g_currentConst.strLabelName, (char*)$1);
            			    g_vecConst.push_back(g_currentConst);
                            free((char*)$1);
			             } 
    	;

CONST:  HEX     
                {
        			g_currentConst.type = HEX_CONST;
	    	        g_currentConst.constData.hexVal = $1;
    	        }
        | DECIMAL
                {
        			g_currentConst.type = DEC_CONST;
		        	g_currentConst.constData.decVal = $1;
    		    }
    	| LABEL 
                {
        		    g_currentConst.type = LABEL_CONST;
                    strcpy(g_currentConst.constData.labelVal, (char*)$1);
                    free((char*)$1);
		        }
        | STR 
                {
                    g_currentConst.type = STR_CONST;
                    strcpy(g_currentConst.constData.strVal, g_strCurrentStrConst.c_str());
                }
	  ;

EXECPART: EXECSTMT EXECPART{cout << " parse:" << g_lCurrentParseCodeNumber << endl;} | EXECSTMT;

EXECSTMT: MEMSTMT | 
	      MATHSTMT |
	      LOGSTMT | 
	      RELSTMT |
	      CONDSTMT | 
          STACKSTMT|
	      PROCSTMT |
          MACROSTMT

MEMSTMT: LDSTMT | LEASTMT | STSTMT

LDSTMT:  LBLSTMT LD GR','EA 
                    {
                        //如果标号不为空
                        if (NULL != $1)
                        {
                            g_mapLabel.insert(LabelMap::value_type(g_lCurrentParseCodeNumber, (char*)$1));
                            free((char*)$1);
                        }
                        
                        //对于每条指令前的标号应当怎样处理呢?
                        //应当定义一张标号表,然后将遇到的所有的标号都
                        //存放到标号表中,但是怎样将标号与实际的指令对应起来呢?
                        //考虑在程序中定义一个当前编译PC指针用来标识当前指令的
                        //位置,这样就可以在最后依据这个位置编号来确定标号所对应的指令的偏移
                        //而对于常量定义,变量定义就不参与PC指针的记数,
                        //而是在生成中间代码以后,依据,常量表,变量表,为所有的变量,常量
                        //分配空间,然后将程序中引用到变量,常量的地方改为变量,常量的地址值
                        g_tempCode.type = CASL_LD;
                        g_tempCode.operand1.type = REG_OPERAND;
                        g_tempCode.operand1.OperandVal.regOperand.regNumber = g_iCurrentRegNumber;
                        g_tempCode.operand2.type = EA_OPERAND;
                        //对于EA地址操作数的处理比较麻烦!!!!!!
                        g_tempCode.operand2.OperandVal.eaOperand.regNumber = g_iCurrentEARegNumber;
                        g_tempCode.operand2.OperandVal.eaOperand.address = g_currentEAAddress;
                        g_vecIntermediateCode.push_back(g_tempCode);   
                        //将下一个Parse的代码的编号加一
                        g_lCurrentParseCodeNumber++;
                    }
         ;

LBLSTMT: LABEL  {$$ = $1;}
         |  {$$ = NULL;};

GR: GR0  
        {
            g_iCurrentRegNumber = 0;
        }
    | GR1
        {
            g_iCurrentRegNumber = 1;
        }
    | GR2
        {
            g_iCurrentRegNumber = 2;
        }
    | GR3
        {
            g_iCurrentRegNumber = 3;
        }
    | GR4 
        {
            g_iCurrentRegNumber = 4;
        }
    ;

EA: ADDR XRADDR
                {

                }
    ;

ADDR: DECIMAL 
                {
                    g_currentEAAddress.type = DEC_EA_ADDRESS;
                    g_currentEAAddress.addressVal.decAddress = $1;
                }
      | LABEL
                {
                    //对于标号地址,应当先到标号表中查询看有无对应项,如果有的话,就应当
                    //将查询到的地址放入g_eaAddressVal中
                    //如果没有的话,就应当在标号表的指定标号中
                    //加入一个回填项以便于在parse过程中如果遇到了指定的标号
                    //进行标号数据的回填
                    g_currentEAAddress.type = LABEL_EA_ADDRESS;
                    strcpy(g_currentEAAddress.addressVal.labelAddress.strLabelName, (char*)$1);
                    free((char*)$1);
                }
      ;

XRADDR: ','XR 
                {
                    //g_iCurrentEARegNumber = g_iCurrentRegNumber;
                }
        |
                {
                    g_iCurrentEARegNumber = REG_NONE;
                }
        ;

XR: GR0  
        {
            g_iCurrentEARegNumber = 0;
        }
    | GR1
        {
            g_iCurrentEARegNumber = 1;
        }
    | GR2
        {
            g_iCurrentEARegNumber = 2;
        }
    | GR3
        {
            g_iCurrentEARegNumber = 3;
        }
    | GR4 
        {
            g_iCurrentEARegNumber = 4;
        }
    ;

STSTMT: LBLSTMT ST GR','EA 
                            {
                                            
                                if (NULL != $1)
                                {
                                    g_mapLabel.insert(LabelMap::value_type(g_lCurrentParseCodeNumber, (char*)$1));
                                    free((char*)$1);
                                }
                                g_tempCode.type = CASL_ST;
                                g_tempCode.operand1.type = REG_OPERAND;
                                g_tempCode.operand1.OperandVal.regOperand.regNumber = g_iCurrentRegNumber;
                                g_tempCode.operand2.type = EA_OPERAND;
                                //对于EA地址操作数的处理比较麻烦!!!!!!
                                g_tempCode.operand2.OperandVal.eaOperand.regNumber = g_iCurrentEARegNumber;
                                g_tempCode.operand2.OperandVal.eaOperand.address = g_currentEAAddress;
                                g_vecIntermediateCode.push_back(g_tempCode);   
                                //将下一个Parse的代码的编号加一
                                g_lCurrentParseCodeNumber++;

                            }

        ;
LEASTMT: LBLSTMT LEA GR','EA  
                            {

                                if (NULL != $1)
                                {
                                    g_mapLabel.insert(LabelMap::value_type(g_lCurrentParseCodeNumber, (char*)$1));
                                    free((char*)$1);
                                }
                                g_tempCode.type = CASL_LEA;
                                g_tempCode.operand1.type = REG_OPERAND;
                                g_tempCode.operand1.OperandVal.regOperand.regNumber = g_iCurrentRegNumber;
                                g_tempCode.operand2.type = EA_OPERAND;
                                g_tempCode.operand2.OperandVal.eaOperand.regNumber = g_iCurrentEARegNumber;
                                g_tempCode.operand2.OperandVal.eaOperand.address = g_currentEAAddress;
                                g_vecIntermediateCode.push_back(g_tempCode);   
                                //将下一个Parse的代码的编号加一
                                g_lCurrentParseCodeNumber++;

                            }

                            ;
MATHSTMT: ADDSTMT | SUBSTMT; 


ADDSTMT: LBLSTMT ADD GR','EA
                            {

                                if (NULL != $1)
                                {
                                    g_mapLabel.insert(LabelMap::value_type(g_lCurrentParseCodeNumber, (char*)$1));
                                    free((char*)$1);
                                }
                                g_tempCode.type = CASL_ADD;
                                g_tempCode.operand1.type = REG_OPERAND;
                                g_tempCode.operand1.OperandVal.regOperand.regNumber = g_iCurrentRegNumber;
                                g_tempCode.operand2.type = EA_OPERAND;
                                g_tempCode.operand2.OperandVal.eaOperand.regNumber = g_iCurrentEARegNumber;
                                g_tempCode.operand2.OperandVal.eaOperand.address = g_currentEAAddress;
                                g_vecIntermediateCode.push_back(g_tempCode);   
                                //将下一个Parse的代码的编号加一
                                g_lCurrentParseCodeNumber++;

                            }
                            ;
SUBSTMT: LBLSTMT SUB GR ',' EA

⌨️ 快捷键说明

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