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

📄 用yacclex设计实现小型basic语言.txt

📁 本文包含简单中文说明和详细源代码
💻 TXT
📖 第 1 页 / 共 5 页
字号:
"then"        { SetInteger(THEN);return THEN; }

"else"        { SetInteger(ELSE);return ELSE; }

"for"         { SetInteger(FOR);return FOR; }

"while" { SetInteger(WHILE);return WHILE; }

"to"        { SetInteger(TO);return TO; }

"downto" { SetInteger(DOWNTO);return DOWNTO; }

"do"        { SetInteger(DO);return DO; }

"of"        { SetInteger(OF);return OF; }

"record" { SetInteger(RECORD);return RECORD; }

"with"  { SetInteger(WITH);return WITH;}

 

 

("quit"|"q")  { SetInteger(EXIT);return EXIT; }

("exit"|"e")  { SetInteger(EXIT);return EXIT; }

("print"|"?") {SetInteger(PRINT);return PRINT;}

"run"        { SetInteger(RUN);return RUN;}

 

 

 

{Letter}{Id}*                        {

                                        /* ID */

                                        SetString(yytext);

                                        return ID;

                                }

\"({NQUOTE}|\"\")*\"                 {

                                        /* short string */

                                        SetString(yytext);

                                        DeleteChar('\"');

                                        return SHORTSTRING;

                                }

{DecDigit}{Digit}*                        {

                                        /* dec */

                                        SetDWord(strtoul(yytext,NULL,10));

                                        return(UNSIGNED_NUMBER);

                                }

{Zero}{OctDigit}*                {        /* oct */

                                        SetDWord(strtoul(yytext,NULL,8));

                                        return(UNSIGNED_NUMBER);

                                }

{Zero}{HexPrev}{HexDigit}+        {        /* hex */

                                        SetDWord(strtoul(yytext,NULL,16));

                                        return(UNSIGNED_NUMBER);

                                }

{Digit}+"."{Digit}+                {

                                        /* float */

                                        SetReal(atof(yytext));

                                        return(REALNUMBER);

                                }

{Digit}+"."{Digit}+[Ee][+-]?{Digit}+        {

                                        /* sce */

                                        SetReal(atof(yytext));

                                        return(REALNUMBER);

                                }

"//".*                                ;        { /* line comments */ }

{SPACE}                                ;

.                                |

 

%%

 

 

6、  语法分析:使用YACC来生成语法数。这里同时就生成了代码,没有考虑代码优化的问题。



%{

 

%}

// 这是 Token 的数据结构

%Union {

        int Integer;

        DWord UnsignedNumber;

        double Real;

        Char *String;

        struct {

                double noused;

                int Type;

        } Info;

}

 

%token UNSIGNED_NUMBER REALNUMBER SHORTSTRING ID

 

%token LT LE EQUAL NE GE GT ASSIGN

%token PLUS MINUS STAR SLASH MOD SHL SHR BITNOT BITAND BITOR

%token LPAREN RPAREN OR AND NOT COMMA SEMICOLON COLON DOT

%token LBRACKET RBRACKET BIGLPAREN BIGRPAREN

 

%token DIM AS ARRAY CASE FUNCTION PROCEDURE PROGRAM LABEL

%token CHAR BYTE INTEGER DWORD REAL STRING

 

%token RECORD CONST BYVAL

%token IF THEN ELSE FOR TO DOWNTO DO WHILE OF GOTO WITH

%token EXIT PRINT RUN

 

%type <Real> REALNUMBER

%type <UnsignedNumber> UNSIGNED_NUMBER

%type <String> SHORTSTRING ID

 

%type <Integer> LT LE EQUAL NE GE GT ASSIGN

%type <Integer> PLUS MINUS STAR SLASH MOD SHL SHR BITNOT BITAND BITOR

%type <Integer> LPAREN RPAREN OR AND NOT COMMA SEMICOLON COLON DOT

%type <Integer> LBRACKET RBRACKET BIGLPAREN BIGRPAREN

%type <Integer> DIM AS ARRAY CASE FUNCTION PROCEDURE PROGRAM LABEL

%type <Integer> CHAR BYTE INTEGER DWORD REAL STRING

%type <Integer> IF THEN ELSE FOR TO DOWNTO WHILE OF GOTO WITH

%type <Integer> RECORD CONST BYVAL

%type <Integer> EXIT PRINT RUN

 

%type <Integer> relop addop mulop signop datatype logicop

 

%type <Integer> variable variable_list label

 

%type <Integer> primary factor term expression simple_expression expr expr_list

 

%type <Integer> compilation_unit program program_header block

 

%type <Integer> decl_sect_list decl_sect proc_decl func_decl param_list

 

%type <Integer> proc_header func_header proc_block fp_list fp_sect_list fp_sect

 

%type <Integer> compound_statement stmt_list stmt normal_stmt

 

%type <Integer> dim_statement goto_statement for_statement if_statement

%type <Integer> while_statement with_statement assign_statement proccall_statement

 

 

%type <Integer> run_statement

 

%type <Integer> print_statement print_expr_list print_dot

 

%right THEN ELSE        // 个别需要右结合的 Token

 

%%

 

compilation_unit:program

 

;

program:program_header block

        ;

program_header: {}

        |PROGRAM

        |PROGRAM ID SEMICOLON

        ;

block        :decl_sect_list compound_statement

        ;

decl_sect_list: {}

        |decl_sect_list decl_sect

        ;

decl_sect:proc_decl

        |func_decl

        ;

proc_decl:proc_header proc_block

        ;

func_decl:func_header proc_block

        ;

proc_header:PROCEDURE ID fp_list

        ;

func_header:FUNCTION ID fp_list AS datatype

        ;

proc_block:block

        ;

fp_list:{}

        |LPAREN fp_sect_list RPAREN

        ;

fp_sect_list:fp_sect

        |fp_sect_list SEMICOLON fp_sect

        ;

fp_sect:variable_list AS datatype

        |BYVAL variable_list AS datatype

        ;

 

compound_statement:BIGLPAREN stmt_list BIGRPAREN

        ;

stmt_list:stmt

        |stmt_list SEMICOLON stmt

        ;

stmt:normal_stmt

        |label COLON normal_stmt

        ;

normal_stmt:{}        /* empty */

        |dim_statement

        |assign_statement

        |proccall_statement

        |goto_statement

        |compound_statement

        |if_statement

        |for_statement

        |while_statement

        |with_statement

        |print_statement

        |run_statement

        ;

run_statement:RUN {exec();}

        |EXIT {exit(0);}

print_statement:PRINT print_expr_list { WriteCode(C_PRINT_LINE); }

        ;

print_expr_list:expr { WriteCode(C_PRINT_EXPR);}

        |print_expr_list print_dot expr {WriteCode(C_PRINT_EXPR);}

        ;

print_dot:COMMA {WriteCode(C_PRINT_COMMA);}

        |COLON {WriteCode(C_PRINT_SEMICOLON);}

        ;

dim_statement:DIM variable AS datatype  {

PVariant p;

        p=GetData($2);

        VarSetType(p,$4);

}

        ;

assign_statement:variable ASSIGN expr {

        WriteCode2(C_POPVAR,$1);

}

        ;

proccall_statement:ID param_list {}

        ;

goto_statement:GOTO label {WriteCode2(C_JMP,$2);}

        ;

label        :ID {

DWord d;

        d=GetVar($1);

        if(d==OUTOFSTRINGINDEX) {

                d=GetIP();

                EnterVar($1,d);

        }

        $$=d;

}

        ;

if_statement:IF  expr {

        WriteCode(C_POPCMP);

        $2=GetIP();

        WriteCode2(C_JEQ,0);

} THEN stmt {

        SetCode($2+1,GetIP());

}

        ;

while_statement:WHILE {

        $1=GetIP();

} expr {

        WriteCode(C_POPCMP);

        $2=GetIP();

         WriteCode2(C_JEQ,0);

} DO stmt {

        WriteCode2(C_JMP,$1);

        SetCode($2+1,GetIP());

}

        ;

for_statement:FOR variable ASSIGN expr {

        $4=GetIP();

        WriteCode2(C_POPVAR,$2);

        WriteCode2(C_PUSHVAR,$2);

} TO expr {

        WriteCode2(C_RELOP,LE);

}

DO {

        WriteCode(C_POPCMP);

        $6=GetIP();

        WriteCode2(C_JEQ,0);

} stmt {

        WriteCode2(C_PUSHVAR,$2);

        WriteCode2(C_PUSHINTEGER,1);

        WriteCode2(C_ADDOP,PLUS);

        WriteCode2(C_JMP,$4);

        SetCode($6+1,GetIP());

}

        ;

with_statement:WITH variable DO stmt

        ;

param_list:        {}/* empty */

        |LPAREN expr_list RPAREN

        ;

expr_list:expr

        |expr_list COMMA expr

        ;

expr:simple_expression

        |NOT simple_expression

        |expr logicop simple_expression

        ;

simple_expression:expression

        |expression relop expression {WriteCode2(C_RELOP,$2);}

        ;

expression:term

        |expression addop term {WriteCode2(C_ADDOP,$2);}

        ;

term        :factor

        |term mulop factor  { WriteCode2(C_MULOP,$2);}

        |BITNOT factor

        ;

factor        :signop factor {WriteCode2(C_SIGNOP,$1);}

        |primary

        ;

primary        :variable {WriteCode2(C_PUSHVAR,$1);}

        |UNSIGNED_NUMBER {  WriteCode2(C_PUSHINTEGER,$1);}

        |REALNUMBER        {

        double r;

        DWord *d;

                WriteCode(C_PUSHREAL);

                r=$1;

                d=(DWord *)&r;

                WriteCode2(*d,*(d+1));

}

        |SHORTSTRING         {

        char *s;

                s=strdup($1);

                WriteCode(C_PUSHSTRING);

                WriteCode((DWord)s);

}

        |LPAREN expr RPAREN

        |ID LPAREN expr_list RPAREN {}         /* type cast, function call */

        ;

logicop :AND

        |OR

        ;

relop        :EQUAL

        |NE

        |LT

        |LE

        |GT

        |GE

        ;

addop        :PLUS

        |MINUS

        ;

mulop        :STAR

        |SLASH

        |MOD

        |SHL

        |SHR

        |BITAND

        |BITOR

        ;

signop        :addop

        ;

variable_list:variable

        |variable_list COMMA variable

        ;

variable:ID {

PSymbolTable q;

PVariant p;

DWord d;

        d=GetVar($1);

        if(d==OUTOFSTRINGINDEX) {

                d=GetFreeDIP();

                EnterVar($1,d);

                InitData(d,NOTYPE);

        }

        $$=d;

}

        |variable LBRACKET expr_list RBRACKET         /* array */

        |variable DOT ID                        /* record */

        |variable '^'                                  /* pointer */

        |ID LPAREN variable RPAREN {}                /* type cast */

⌨️ 快捷键说明

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