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

📄 pl3.y

📁 简介:PL0语言是pascal语言的一个子集。编译VC工程之前
💻 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 + -