?? cc.y
字號:
%{
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include "symbol.h"
#include "conio.h"
#include "stkmach.h"
jmp_buf begin;
char *progname;
char *infile;
FILE *yyin;
char **gargv;
int gargc;
extern yylex();
extern int lineno;
extern Inst progp, progbase;
extern indef;
/*
%token GT GE LT LE EQ NE OR AND NOT
%token PLUS MINUS MUL DIV
%token AS
*/
#define code2(c1,c2) code(c1); code(c2)
#define code3(c1,c2,c3) code(c1); code(c2); code(c3)
%}
%union {
Inst *inst; /* 指令 */
symrec *tptr; /* 符號表指針 */
int narg; /* 參數(shù) */
int delim; /* 分界符(不存入符號表中) */
int op; /* 操作符(不存入符號表中) */
char *str; /* 字符串(不存入符號表中) */
}
%token <delim> NL COMMA
%token <delim> LP RP LB RB
%token <op> MINUSMINUS PLUSPLUS PLUSMINUS MINUSPLUS
%token <tptr> NUMBER CONST VAR BLTIN UNDEF PRINT WHILE IF ELSE
%token <tptr> FUNCTION PROCEDURE RETURN FUNC PROC READ
%token <narg> ARG
%token <str> STRING
%type <inst> stmt asgn expr stmtlist cond while if begin end
%type <inst> prlist
%type <narg> arglist
%type <tptr> procname
%right AS
%left OR
%left AND
%left GT GE LT LE EQ NE
%left PLUS MINUS
%left MUL DIV
%left NEG POS NOT
%right POW
%%
list:
| list NL
| list defn NL
| list asgn NL { code2(pop,STOP); return 1; }
| list expr NL { code2(print,STOP); return 1; }
| list stmt NL { code(STOP); return 1; }
| list error NL { yyerrok; }
;
asgn: VAR AS expr { $$ = $3; code3(varpush, (Inst)$1, assign); }
| ARG AS expr
{ defnonly("$"); code2(argassign, (Inst)$1); $$ = $3; }
;
stmt: expr { code(pop); }
| RETURN { defnonly("return"); code(procret); }
| RETURN expr
{ defnonly("return"); $$ = $2; code(funcret); }
| PROCEDURE begin LP arglist RP
{ $$ = $2; code3(call, (Inst)$1, (Inst)$4); }
| PRINT prlist =
{ $$ = $2; }
| while cond stmt end {
($1)[1] = (Inst)$3; /* body of loop */
($1)[2] = (Inst)$4; /* end, if cond fails */
}
| if cond stmt end { /* else-less if */
($1)[1] = (Inst)$3; /* thenpart*/
($1)[3] = (Inst)$4; /* end, if cond fails */
}
| if cond stmt end ELSE stmt end { /* if with else */
($1)[1] = (Inst)$3; /* thenpart*/
($1)[2] = (Inst)$6; /* elsepart*/
($1)[3] = (Inst)$7; /* end, if cond fails */
}
| LB stmtlist RB { $$ = $2; }
;
cond: LP expr RP { code(STOP); $$ = $2; }
;
while: WHILE { $$ = code3(whilecode, STOP, STOP); }
;
if: IF { $$ = code(ifcode); code3(STOP,STOP,STOP); }
;
begin: /*nothing*/ { $$ = progp; }
;
end: /* nothing */ { code(STOP); $$ = progp; }
;
stmtlist: /* nothing */ { $$ = progp; }
| stmtlist NL
| stmtlist stmt
;
expr:NUMBER { $$ = code2(constpush, (Inst)$1); }
| CONST { $$ = code2(constpush, (Inst)$1); }
| VAR { $$ = code3(varpush, (Inst)$1, eval); }
| ARG { defnonly("$"); $$ = code2(arg, (Inst)$1); }
| asgn
| FUNCTION begin LP arglist RP
{ $$ = $2, code3(call, (Inst)$1, (Inst)$4); }
| READ LP VAR RP { $$ = code2(varread, (Inst)$3); }
| BLTIN LP expr RP { $$ = $3; code2(bltin, (Inst)$1->value.fnctptr); }
| LP expr RP { $$ = $2; }
| PLUS expr %prec POS { $$ = $2; }
| expr PLUS expr { code(add); }
| expr MINUS expr { code(sub); }
| expr MUL expr { code(mul); }
| expr DIV expr { code(divi); }
| expr POW expr { code(power); }
| MINUS expr %prec NEG { $$ = $2; code(neg); }
| expr GT expr { code(gt); }
| expr GE expr { code(ge); }
| expr LT expr { code(lt); }
| expr LE expr { code(le); }
| expr EQ expr { code(eq); }
| expr NE expr { code(ne); }
| expr AND expr { code(and); }
| expr OR expr { code(or); }
| NOT expr { $$ = $2; code(not); }
;
prlist: expr { code(prexpr); }
| STRING { $$ = code2(prstr, (Inst)$1); }
| prlist COMMA expr { code(prexpr); }
| prlist COMMA STRING { code2(prstr, (Inst)$3); }
defn: FUNC procname { $2->type = FUNCTION; indef = 1; }
LP RP stmt { define($2); indef = 0; } /*code(funcret);*/
| PROC procname { $2->type = PROCEDURE; indef = 1; }
LP RP stmt { define($2); indef = 0; } /*code(procret);*/
;
procname: VAR
| FUNCTION
| PROCEDURE
;
arglist: /*nothing*/ { $$ = 0; }
| expr { $$ = 1; }
| arglist COMMA expr { $$ = $1 + 1; }
;
%%
enum TOK {
$DIM=1,$IF
};
main(int argc, char *argv[])
{
int fpecatch();
progname = argv[0];
if (argc == 1)
{
static char *stdinonly[] = { "-" };
gargv = stdinonly;
gargc = 1;
}
else
{
gargv = argv + 1;
gargc = argc - 1;
}
init_table();
while (moreinput())
run();
return 0;
}
moreinput()
{
if (gargc-- <= 0)
return 0;
infile = *gargv++;
lineno = 1;
if (strcmp(infile, "-") == 0)
{
yyin = stdin;
infile = 0;
}
else if ((yyin = fopen(infile, "r")) == NULL)
{
fprintf(stderr, "%s: cant't open %s\n", progname, infile);
return moreinput();
}
return 1;
}
run()
{
setjmp(begin);
signal(SIGFPE, fpecatch);
for (initcode(); yyparse(); initcode())
excute(progbase);
}
warning(char *s, char *t)
{
fprintf(stderr, "%s: %s", progname, s);
if (t)
fprintf(stderr, " %s", t);
fprintf(stderr, " near line %d\n", lineno);
}
yyerror(char *s)
{
warning(s,(char*) 0);
}
execerror(char *s, char *t)
{
warning(s, t);
longjmp(begin, 0);
}
fpecatch()
{
execerror("floating point exception", (char *) 0);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -