📄 pl3.y
字号:
%union{
char *name;
int value;
int val;
}
%{
void yyerror(char *str);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <memory.h>
#include "define.h"
extern int yylex();
extern int lineno;
yyltype my_yylloc;
%}
%start program
%type <val> array_bound sign expression_list relation_opr add_opr multi_opr
%type <name> id var_ref
%token BEGINSYM ENDSYM CONST VAR PROCEDURE REPEAT UNTIL WHILE CALL DO READ WRITE COLEQ ODD
%token <name> LEGAL_ID
%token <val> NUMBER
%left LE RE IF
%left '+' '-' THEN
%left '*' '/' ELSE
%%
program:
subprogram '.'
;
subprogram: tmp_cx { lev++; gen(JMP, 0, 0); }
const_dec var_dec procedure_dec { code[$<val>1].a=cx; proc_dec(); }
statement { gen(OPR, 0, 0); lev--; }
;
const_dec:
CONST const_dec_list ';'
|
;
const_dec_list:
const_dec_list ','const_def
|const_def
;
const_def:
id '=' NUMBER { kind=constant; num=$<val>3; enter($<name>1); }
;
var_dec:
VAR var_dec_list ';'
|
;
var_dec_list:
var_def
|var_dec_list ',' var_def
;
var_def:
id { kind=variable; enter($<name>1); }
|id '(' bound_pair ')' { kind=var_array; enter($<name>1);}
;
bound_pair:
array_bound ':' array_bound { dx1=$<val>1; dx2=$<val>3;}
;
array_bound:
id { $<val>$=array_bound($<name>1); }
|NUMBER { $<val>$=$<val>1;}
;
procedure_dec:
procedure_dec PROCEDURE procedure_head subprogram ';'
|
;
procedure_head:
id { kind=procedure; enter($<name>1); } ';'
|id { kind=procedure;enter($<name>1); } '(' para_list ')' ';'
;
para_list:
id { kind=parameter; enter($<name>1);}
|para_list ',' id { kind=parameter; enter($<name>3);}
;
id:
LEGAL_ID { $<name>$=$<name>1;}
;
tmp_cx:
{$<val>$=cx; }
;
tmp_jpc:
{$<val>$=cx;gendo(JPC,0,0);}
;
tmp_else:
{ $<val>$=cx; gen(JMP,0,0); code[$<val>-1].a=cx; }
;
statement:
Cstmt
|Ostmt
;
Cstmt:
var_ref COLEQ expression {asgn_stmt($<name>1);}
|IF cond THEN tmp_jpc Cstmt tmp_else ELSE Cstmt {code[$<val>6].a=cx; }
|BEGINSYM statement_list ENDSYM
|CALL id arguments {call_stmt($<name>2,$<val>3); }
|READ '(' read_list ')' { }
|WRITE '(' write_list ')' {gendo(OPR, 0, 15); }
|WHILE tmp_cx cond tmp_jpc DO Cstmt {gendo(JMP,0,$<val>2);code[$<val>4].a=cx; }
|REPEAT tmp_cx statement UNTIL cond {gendo(JPC,0,$<val>2);}
|
;
Ostmt:
IF cond THEN tmp_jpc statement {code[$<val>4].a=cx; }
|IF cond THEN tmp_jpc Cstmt tmp_else ELSE Ostmt {code[$<val>6].a=cx; }
|WHILE tmp_cx cond tmp_jpc DO Ostmt {gendo(JMP,0,$<val>2); code[$<val>4].a=cx;}
;
statement_list:
statement
|statement_list ';' statement
;
arguments:
/* */ { $<val>$=0; }
|'(' expression_list ')' { $<val>$=$<val>2; }
;
var_ref:
id { $<name>$=$<name>1; }
|id '(' expression ')' { $<name>$=$<name>1; array_access($<name>1); }
;
read_list:
var_ref { read_stmt($<name>1); }
|read_list ',' var_ref { read_stmt($<name>3); }
;
expression_list:
expression {$<val>$=1;}
|expression_list ',' expression {$<val>$++;}
;
write_list:
expression {gendo(OPR, 0, 14);}
|write_list ',' expression {gendo(OPR, 0, 14);}
;
cond:
ODD expression {gendo(OPR,0,6);}
|expression relation_opr expression {exp_r_exp($<val>2);}
;
relation_opr:
'=' {$<val>$=eql;}
|'<' {$<val>$=lss;}
|'>' {$<val>$=gtr;}
|'#' {$<val>$=neq;}
|LE {$<val>$=leq;}
|RE {$<val>$=geq;}
;
expression:
sign term {operate($<val>1);}
|expression add_opr term {operate($<val>2);}
;
sign:
'+' {$<val>$='p';}
|'-' {$<val>$='n';}
| {$<val>$='p';}
;
add_opr:
'+' {$<val>$='+';}
|'-' {$<val>$='-';}
;
multi_opr:
'*' {$<val>$='*';}
|'/' {$<val>$='/';}
;
term:
factor
|term multi_opr factor {operate($<val>2);}
;
factor:
var_ref {factor_var($<name>1);}
|NUMBER {gendo(LIT,0,$<val>1);}
|'(' expression ')'
;
%%
void yyerror(char *str)
{
if(str == "parse error")
return;
printf("\nError in Line %d : %s",lineno,str);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -