📄 checker.y
字号:
%{
#include <string>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <vector>
#include <list>
#include "CHKsupport.cpp"
using namespace std;
struct __yystype {
int intval;
list <int> int_list;
string strval;
list <TSymbolListVariableEntry> Ventry_list;
TSymbolListVariableEntry Ventry;
TSymbolListTypeEntry Tentry;
TSymbolListFunctionEntry Fentry;
};
extern int PROGRAM_EOF;
extern int PROGRAM_LineNumber;
extern char* PROGRAM_FileName;
#define YYSTYPE __yystype
int yyerror(string msg)
{
Tmsg tmpmsg;
tmpmsg.lineno = PROGRAM_LineNumber;
if (PROGRAM_EOF)
{
tmpmsg.msgtxt = "1: " + msg + " before *end of file*";
}
else
{
tmpmsg.msgtxt = "1: " + msg + " before \"" + yytext + "\"";
}
tmpmsg.sourcecount = error_msgs.size();
error_msgs.push_back(tmpmsg);
return 0;
}
int yylex();
int InFuncLevel = -1;
int InLoopCount = 0;
int PROGRAM_func_ret;
%}
%token NIL
%token <intval> IDENT
%token <intval> TRUE FALSE INT SYMNULL CHAR DOUBLE
%token <strval> STRING
%token IF ELSE FOR WHILE BREAK RETURN
%token PRINT READINT READDBL READLINE NEW
%token LPAREN RPAREN LBRACKET RBRACKET LSQUARE RSQUARE DOT COMMA SEMICOLON
%token TYPEINT TYPEDOUBLE TYPEBOOL TYPESTRING TYPEVOID TYPECHAR CLASS EXTENDS THIS
%token STRUCT CONST
%token READREG WRITEREG ASM
%right LET
%left LOGICOR
%left LOGICAND
%left LES GTR LEQ GEQ EQL NEQ
%left OR
%left CALCNOT
%left AND XOR SHL SHR
%left ADD MINUS
%left MUL DIV MOD
%left STAR REF FORCE
%left UMINUS NOT
%left DOT LSQUARE RSQUARE
%left PPLUS MMINUS
%left LPAREN RPAREN
%type <intval> basictype
%type <Ventry> expr arraysub call
%type <Ventry_list> actuals exprs types
%type <int_list> varlist
%type <Ventry_list> funcvars formals
%type <Ventry> funcvar
%type <Tentry> fieldblock fields
%type <Fentry> funcdecl funcdef
%nonassoc IFX
%nonassoc ELSE
%start program
%%
program : decls { }
;
decls : decls decl { }
| decl { }
;
decl : vardecl { CheckMakeNewVarDecls($1.intval, $1.int_list); }
| funcdef { CheckMakeNewFuncDef($1); }
| funcdecl { CheckMakeNewFuncDecl($1); }
| structdef { }
| error { }
;
varlist : IDENT { $$.clear(); $$.push_back($1); }
| varlist COMMA IDENT { $$ = $1; $$.push_back($3); }
;
vardecl : var SEMICOLON { $$ = $1; }
| var COMMA varlist SEMICOLON { $$.intval = $1.intval;
$$.int_list = $3;
$$.int_list.push_front(*$1.int_list.begin()); }
| CONST type IDENT LET expr SEMICOLON { CheckAddConstVariable(SymbolListTypeADDArrayList($2.intval, $2.int_list), $3, $5);
}
;
arraysub : LSQUARE expr RSQUARE { $$ = $2; }
;
var : type IDENT { $$.intval = SymbolListTypeADDArrayList($1.intval, $1.int_list);
$$.int_list.clear(); $$.int_list.push_back($2); }
;
types : type { $$.clear();
TSymbolListVariableEntry Ventry;
Ventry.var_type = SymbolListTypeADDArrayList($1.intval, $1.int_list);
$$.push_back(Ventry); }
| types COMMA type { $$ = $1;
TSymbolListVariableEntry Ventry;
Ventry.var_type = SymbolListTypeADDArrayList($3.intval, $3.int_list);
$$.push_back(Ventry); }
;
type : basictype { $$.intval = $1; $$.int_list.clear(); }
| type MUL { $$.intval = SymbolListTypeADDArrayList($1.intval, $1.int_list);
$$.intval = SymbolListTypeADDStar($$.intval);
$$.int_list.clear(); }
| type arraysub { $$.intval = $1.intval; $$.int_list = $1.int_list;
$$.int_list.push_back(CheckArraysubToConst($2)); }
| type LPAREN RPAREN LPAREN types RPAREN { $$.intval = SymbolListMakeFunctionType(SymbolListTypeADDArrayList($1.intval, $1.int_list),
$5);
$$.int_list.clear(); }
;
basictype : TYPEINT { $$ = var_type_int; }
| TYPECHAR { $$ = var_type_char; }
| TYPEVOID { $$ = var_type_void; }
| STRUCT IDENT { if (SymbolListType[$2].total_size == type_undefined )
{
errormsg(4, PROGRAM_LineNumber, IDHash_int2ID($2));
$$ = var_type_notfound;
}
else
{
$$ = $2;
}
}
;
funcdecl : type IDENT LPAREN formals RPAREN SEMICOLON { TSymbolListFunctionEntry Fentry;
Fentry.defined = 0;
Fentry.id = $2; Fentry.arg_list = $4;
Fentry.func_type = SymbolListMakeFunctionType(SymbolListTypeADDArrayList($1.intval, $1.int_list), $4);
Fentry.defined_line = PROGRAM_LineNumber; Fentry.valid = 1;
$$ = Fentry; }
;
formals : funcvars { $$ = $1; }
| /* epsilon */ { $$.clear(); }
;
funcvars : funcvar { $$.clear(); $$.push_back($1); }
| funcvars COMMA funcvar { $$ = $1; $$.push_back($3); }
;
funcvar : var { $$.var_type = $1.intval; $$.defined_line = PROGRAM_LineNumber;
$$.id = *$1.int_list.begin();
$$.const_sign = 0; $$.lvalue = 1; }
;
funcdef : type IDENT LPAREN formals RPAREN { TSymbolListFunctionEntry Fentry;
Fentry.id = $2; Fentry.arg_list = $4;
Fentry.func_type = SymbolListMakeFunctionType(SymbolListTypeADDArrayList($1.intval, $1.int_list), $4);
Fentry.defined_line = PROGRAM_LineNumber; Fentry.valid = 1;
CheckMakeNewFuncDecl(Fentry);
$$ = Fentry;
PROGRAM_func_ret = SymbolListTypeADDArrayList($1.intval, $1.int_list);
SymbolListIncLevel();
for (list <TSymbolListVariableEntry> :: iterator p = $4.begin(); p != $4.end(); p ++)
{
CheckMakeNewVarDecl(*p);
}
SymbolListNowLevel --; }
stmtblock { $$ = $6.Fentry; }
;
structdef : STRUCT IDENT { $$.intval = PROGRAM_LineNumber; }
fieldblock SEMICOLON { CheckMakeNewStructDef($2, $4, $3.intval); }
;
fieldblock : LBRACKET fields RBRACKET { $$ = $2; }
| LBRACKET RBRACKET { SymbolListMakeNewStruct($$); }
;
fields : vardecl { SymbolListMakeNewStruct($$);
AddVars2Field($$, $1.intval, $1.int_list); }
| fields vardecl { $$ = $1;
AddVars2Field($$, $2.intval, $2.int_list); }
;
stmtblock : LBRACKET { SymbolListIncLevel(); }
stmtstar RBRACKET { SymbolListDecLevel(); }
;
stmtstar : stmts { }
| /* epsilon */ { }
;
stmts : stmts stmt { }
| stmt { }
;
asmstar : asms { }
| /* epsilon */ { }
;
asms : asms asm { }
| asm { }
;
asm : ASM LPAREN INT RPAREN SEMICOLON { }
| ASM LPAREN STRING RPAREN SEMICOLON { CheckASM(0, $3); }
| ASM LPAREN STRING COMMA STRING RPAREN SEMICOLON { CheckASM(1, $3, $5); }
| ASM LPAREN STRING COMMA STRING COMMA STRING RPAREN SEMICOLON
{ CheckASM(2, $3, $5, $7); }
| ASM LPAREN STRING COMMA STRING COMMA STRING COMMA STRING RPAREN SEMICOLON
{ CheckASM(3, $3, $5, $7, $9); }
| READREG LPAREN STRING COMMA IDENT RPAREN SEMICOLON
{ CheckRegOperation(REG_OP_READ, $3, $5); }
| WRITEREG LPAREN STRING COMMA IDENT RPAREN SEMICOLON
{ CheckRegOperation(REG_OP_WRITE, $3, $5); }
;
stmt : stmtblock { }
| vardecl { CheckMakeNewVarDecls($1.intval, $1.int_list); }
| simplestmt SEMICOLON { }
| ifstmt { }
| whilestmt { }
| forstmt { }
| breakstmt SEMICOLON { }
| returnstmt SEMICOLON { }
| ASM LBRACKET asmstar RBRACKET SEMICOLON { }
| error { }
;
simplestmt : expr { }
| /* epsilon */ { }
;
call : expr LPAREN actuals RPAREN { CheckCall($1, $3, $$); }
;
actuals : exprs { $$ = $1; }
| /* epsilon */ { $$.clear(); }
;
forstmt : FOR LPAREN simplestmt SEMICOLON expr { CheckCondExpr($5); }
SEMICOLON simplestmt RPAREN { InLoopCount ++; }
stmt { InLoopCount --; }
;
whilestmt : WHILE LPAREN expr RPAREN { CheckCondExpr($3); InLoopCount ++; }
stmt { InLoopCount --; }
;
ifpart : IF LPAREN expr RPAREN { CheckCondExpr($3); }
ifstmt : ifpart stmt %prec IFX {}
| ifpart stmt ELSE stmt {}
;
returnstmt : RETURN { if (PROGRAM_func_ret != var_type_void)
errormsg(21, PROGRAM_LineNumber, "void", __vartype2str(PROGRAM_func_ret));
}
| RETURN expr { if (!CheckCastCompatibility(PROGRAM_func_ret, $2))
errormsg(21, PROGRAM_LineNumber, __vartype2str($2), __vartype2str(PROGRAM_func_ret));
}
;
breakstmt : BREAK { if (InLoopCount == 0) errormsg(30, PROGRAM_LineNumber);
}
;
exprs : expr { $$.clear(); $$.push_back($1); }
| exprs COMMA expr { $$ = $1; $$.push_back($3); }
;
intblock : ints GTR { }
| LES GTR { }
;
ints : LES INT { }
| ints COMMA INT { }
;
expr : IDENT { GetVariable($1, $$); }
| LPAREN type RPAREN expr %prec FORCE { ForceCast($4, SymbolListTypeADDArrayList($2.intval, $2.int_list), $$); }
| expr DOT IDENT { GetFieldVariable($1, $3, $$); }
| expr arraysub { CheckFindArrayAddr($1, $2, $$); }
| MUL expr %prec STAR { CheckAddPtr($2, $$); }
| INT { MakeConstantIntExpr($$, $1, var_type_int); }
| SYMNULL { MakeConstantIntExpr($$, 0, var_type_NULL); }
| STRING { MakeConstantIntExpr($$, 1, SymbolListTypeADDStar(var_type_char)); }
| TRUE { MakeConstantIntExpr($$, 1, var_type_int); }
| FALSE { MakeConstantIntExpr($$, 0, var_type_int); }
| CHAR { MakeConstantIntExpr($$, $1, var_type_char); }
| intblock { MakeConstantIntExpr($$, 1, SymbolListTypeADDStar(var_type_int)); }
| call { $$ = $1; }
| expr LET expr { CheckMakeLet ($1, $3, $$); }
| LPAREN expr RPAREN { $$ = $2; }
| AND expr %prec REF { CheckAddRef($2, $$); }
| expr LES expr { CheckExprBinaryRelational($1, $3, SRC_relational_LES, $$); }
| expr GTR expr { CheckExprBinaryRelational($1, $3, SRC_relational_GTR, $$); }
| expr LEQ expr { CheckExprBinaryRelational($1, $3, SRC_relational_LEQ, $$); }
| expr GEQ expr { CheckExprBinaryRelational($1, $3, SRC_relational_GEQ, $$); }
| expr EQL expr { CheckExprBinaryRelational($1, $3, SRC_relational_EQL, $$); }
| expr NEQ expr { CheckExprBinaryRelational($1, $3, SRC_relational_NEQ, $$); }
| expr LOGICAND expr { CheckExprBinaryRelational($1, $3, SRC_logical_AND, $$); }
| expr LOGICOR expr { CheckExprBinaryRelational($1, $3, SRC_logical_OR, $$); }
| NOT expr { CheckExprUnaryLogical($2, SRC_logical_NOT, $$); }
| CALCNOT expr { CheckExprUnaryCalculational($2, SRC_calculational_NOT, $$); }
| expr ADD expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_ADD, $$); }
| expr MINUS expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_MINUS, $$); }
| expr MUL expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_MUL, $$); }
| expr DIV expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_DIV, $$); }
| expr MOD expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_MOD, $$); }
| expr AND expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_AND, $$); }
| expr OR expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_OR, $$); }
| expr XOR expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_XOR, $$); }
| expr SHL expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_SHL, $$); }
| expr SHR expr { CheckExprBinaryCalculational($1, $3, SRC_calculational_SHR, $$); }
| MINUS expr %prec UMINUS { CheckExprUnaryCalculational($2, SRC_calculational_MINUS, $$); }
| expr PPLUS { CheckExprSelfAction($1, $$, SRC_calculational_ADD); }
| expr MMINUS { CheckExprSelfAction($1, $$, SRC_calculational_MINUS); }
;
%%
int main(int argc, char* argv[])
{
int filecnt = -1;
for (int i = 1; i < argc; i++)
{
if (filecnt == -1 && argv[i][0] != '-')
{
filecnt = i;
}
}
if (filecnt == -1)
{
printf("checker: no input file\n");
return 1;
}
yyin = fopen(argv[filecnt], "r");
PROGRAM_FileName = argv[filecnt];
if (yyin == NULL)
{
printf("checker: %s: No such file\n", argv[filecnt]);
return 1;
}
yyparse();
if (errormsg_print() && chk_func_defined())
{
return 0;
}
else
{
return 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -