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

📄 语法分析.y

📁 PL语言语法分析器
💻 Y
字号:
%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "lex.yy.c"
%}

%token IF THEN WHILE DO READ WRITE CALL BEG END CONST VAR PROCEDURE ODD/*13个保留字*/
%token ADD MINUS MULTIPLY DIVIDE/*加减乘除*/
%token SEMICOLON LBRACKET RBRACKET COMMA DOT/*分号左括号右括号逗号句号*/
%token ASSIGN DASSIGN JING SMALL BIG SM_EQ BI_EQ/*赋值等于井号小于大于小于等于大于等于*/
%token INDENTIFIER INTEGER ERRORTOKEN/*标识符整数错误*/

/*语法规则*/
%%

program/*程序*/
      : segment DOT {printf("      程序归约为:分程序.\n");}
      ;

segment/*分程序*/
      : const_exp vari_exp proce_exp sentence {printf("      分程序归约为:常量说明部分 变量说明部分 过程说明部分 语句\n");}
      | const_exp vari_exp sentence {printf("      分程序归约为:常量说明部分 变量说明部分 语句\n");}
      | const_exp proce_exp sentence {printf("      分程序归约为:常量说明部分 过程说明部分 语句\n");}
      | vari_exp proce_exp sentence {printf("      分程序归约为:变量说明部分 过程说明部分 语句\n");}
      | const_exp sentence {printf("      分程序归约为:常量说明部分 语句\n");}
      | vari_exp sentence {printf("      分程序归约为:变量说明部分 语句\n");}
      | proce_exp sentence {printf("      分程序归约为:过程说明部分 语句\n");}
      | sentence{printf("      分程序归约为:语句\n");}
      ;

const_exp/*常量说明部分*/
      : CONST const_define const_definelist SEMICOLON  {printf("      常量说明部分归约为:CONST 常量定义 常量定义串;\n");}
      | CONST const_define SEMICOLON  {printf("      常量说明部分归约为:CONST 常量常义;\n");}
      ;

const_definelist/*常量定义串*/ 
      : const_definelist COMMA const_define {printf("      常量定义串归约为:常量定义串,常量定义\n");}
      | COMMA const_define {printf("      常量定义串归约为:,常量定义\n");}
      ;

const_define/*常量定义*/
      : INDENTIFIER DASSIGN INTEGER {printf("      常量定义归约为:标识符=整数\n");}
      ;

vari_exp/*变量说明部分*/
      : VAR INDENTIFIER ID_list SEMICOLON  {printf("      变量说明部分归约为:VAR 标识符 标识符串 ;\n");}
      | VAR INDENTIFIER SEMICOLON  {printf("      变量说明部分归约为:VAR 标识符 ;\n");} 
      ;

ID_list/*标识符串*/
      : COMMA INDENTIFIER {printf("      标识符串归约为:,标识符\n");}
      | ID_list COMMA INDENTIFIER  {printf("      标识符串归约为:标识符串, 标识符\n");}
      ;

proce_exp/*过程说明部分*/
      : proce_head segment pro_explist SEMICOLON {printf("      过程说明部分归约为:过程首部 分程序 过程说明串 ;\n");}
      | proce_head segment SEMICOLON  {printf("      过程说明部分归约为:过程首部 分程序 ;\n");}
      ;

pro_explist/*过程说明串*/
      : SEMICOLON proce_exp {printf("      过程说明串归约为:; 过程说明部分\n");}
      | pro_explist SEMICOLON proce_exp {printf("      过程说明串归约为:过程说明串 ; 过程说明部分\n");}
      ;

proce_head/*过程首部*/
      : PROCEDURE INDENTIFIER SEMICOLON  {printf("      过程首部归约为:PROCEDURE 标识符 ;\n");}
      ;

sentence/*语句*/
      : assign_sentence  {printf("      语句归约为:赋值语句\n");}
      | compound_sentence  {printf("      语句归约为:复合语句\n");}
      | if_sentence  {printf("      语句归约为:条件语句\n");}
      | while_sentence  {printf("      语句归约为:当型循环语句\n");}
      | pro_sentence  {printf("      语句归约为:过程调用语句\n");}
      | read_sentence  {printf("      语句归约为:读语句\n");}
      | write_sentence  {printf("      语句归约为:写语句\n");}
      |          {printf("      语句归约为:空语句\n");}
      ;

assign_sentence/*赋值语句*/
      : INDENTIFIER DASSIGN expression  {printf("      赋值语句归约为:标识符 := 表达式\n");}
      ;

compound_sentence/*复合语句*/
      : BEG sentence sentence_list END   {printf("      复合语句归约为:BEGIN 语句 语句串 END\n");}
      | BEG sentence END  {printf("      复合语句归约为:BEGIN 语句 END\n");}
      ;

sentence_list/*语句串*/
      : SEMICOLON sentence {printf("      语句串归约为:; 语句\n");}
      | sentence_list SEMICOLON sentence {printf("      语句串归约为:语句串 ; 语句\n");}
      ;

if_sentence/*条件语句*/
      : IF condition THEN sentence  {printf("      条件语句归约为:IF 条件 THEN 语句\n");}
      ;

condition/*条件*/
      : expression relation_op expression {printf("      条件归约为:表达式 关系运算符 表达式\n");}
      | ODD expression {printf("      条件归约为:ODD 表达式\n");}
      ;

expression/*表达式*/
      : ADD element add_list {printf("      表达式归约为:+ 项 加法和项的串\n");}
      | MINUS element add_list {printf("      表达式归约为:- 项 加法和项的串\n");}
      | element add_list  {printf("      表达式归约为:项 加法和项的串\n");}
      | element  {printf("      表达式归约为:项\n");}
      | ADD element {printf("     表达式归约为:+ 项\n");}
      | MINUS element  {printf("      表达式归约为:- 项\n");}
      ;

add_list/*加法和项的串*/
      : add_list add_op element  {printf("      加法和项的串归约为:加法和项的串 加法运算符 项\n");}
      | add_op element  {printf("      加法和项的串归约为:加法运算符 项\n");}
      ;

element/*项*/
      : factor mul_list {printf("      项归约为:因子 乘法运算符和因子的串\n");}
      | factor  {printf("      项归约为:因子\n");}
      ;

mul_list/*"乘法运算符和因子的串*/
      : mul_list mul_op factor  {printf("      乘法运算符和因子的串归约为:乘法运算符和因子的串 乘法运算符 因子\n");}
      | mul_op factor {printf("      乘法运算符和因子的串归约为:乘法运算符 因子\n");}
      ;

factor/*因子*/
      : INDENTIFIER  {printf("      因子归约为:ID\n");}
      | INTEGER {printf("      因子归约为:NUM\n");}
      | LBRACKET expression RBRACKET  {printf("      因子归约为:( 表达式 )\n");}
      ;

add_op/*加法运算符*/
      : ADD  {printf("      加法运算符归约为:+\n");}
      | MINUS   {printf("      加法运算符归约为:-\n");}
      ;

mul_op/*乘法运算符*/
      : MULTIPLY   {printf("      乘法运算符归约为:*\n");}
      | DIVIDE    {printf("      乘法运算符归约为:/\n");}
      ;

relation_op/*关系运算符*/
      : ASSIGN {printf("      关系运算符归约为:=\n");}
      | JING   {printf("      关系运算符归约为:#\n");}
      | SMALL  {printf("      关系运算符归约为:<\n");}
      | BIG    {printf("      关系运算符归约为:>\n");}
      | SM_EQ  {printf("      关系运算符归约为:<=\n");}
      | BI_EQ  {printf("      关系运算符归约为:>=\n");}
      ;
while_sentence/*当型循环语句*/
      : WHILE condition DO sentence {printf("      当型循环语句归约为:WHILE 条件 DO 语句\n");}
      ;

pro_sentence/*过程调用语句*/
      : CALL INDENTIFIER  {printf("      过程调用语句归约为:CALL 标识符\n");}
      ;

read_sentence/*读语句*/
      : READ LBRACKET INDENTIFIER ID_list RBRACKET  {printf("      读语句归约为:READ ( 标识符 标识符串 )\n");}
      | READ LBRACKET INDENTIFIER RBRACKET   {printf("      读语句归约为:READ ( 标识符 )\n");}
      ;

write_sentence/*写语句*/ 
      : WRITE LBRACKET expression expression_list RBRACKET  {printf("      写语句归约为:WRITE ( 表达式 表达式串 )\n");}
      | WRITE LBRACKET expression RBRACKET  {printf("      写语句归约为:WRITE ( 表达式 )\n");}
      ;

expression_list/*表达式串*/
      : expression_list COMMA expression  {printf("      表达式串归约为:表达式串 , 表达式\n");}
      | COMMA expression  {printf("      表达式串归约为:, 表达式\n");}
      ;

%%

void print()
{
    printf("              **********************************************\n");
    printf("              *               PL0语法分析器                *\n");
    printf("              **********************************************\n\n");
    printf("\n-------------------------PL0语言包含的所有的终结符如下-------------------------\n");
    printf("关键字:IF THEN WHILE DO READ WRITE CALL BEG END CONST VAR PROCEDURE ODD \n");
    printf("运算符有: + - * / \n"); 
    printf("界符有:; ( ) ,\n");
    printf("关系符有:= := # <= >= < >\n");
    printf("标识符为INDENTIFIER 整数为INTEGER\n");
    printf("--------------------------------------------------------------------------\n\n\n\n");
}

int main()
{
    FILE * fp;
    char FILENAME[30];
    char ch;
    print();
    printf("          现在进行语法分析,采用的输入方式是从文件输入。\n");
    printf("          你可以将自己的PL0程序存入文本文件,我们提供了\n");
    printf("          两个PL0程序测试文件:test1.txt和test2.txt\n");
    printf("请输入文件名:\n");
    scanf("%s",FILENAME);
    if((fp=fopen(FILENAME,"r"))==NULL)
    { 
    	printf("对不起,不存在这样的文件!\n");
        return 1;
    }
   printf
("\n********************************************************************************\n");
    printf("你给与的PL0程序如下:\n");
    ch=fgetc(fp);
    while(ch!=EOF)
        {
            putchar(ch);
            ch=fgetc(fp);
         } 
    printf
("\n********************************************************************************\n\n\n");
   /*fclose(fp);
    if((fp=fopen(FILENAME,"r"))==NULL)
    { 
    	printf("对不起,不存在这样的文件!\n");
        return 1;
    }*/
    rewind(fp);
    printf("------------------------------------------------------------------------------\n");
    printf("\n现在开始语法分析:\n\n");
    yyin=fp;
    yyparse();
    fclose(fp);
    printf("                       ------------------------\n");
    printf("                      |       归约成功!        |\n ");
    printf("                      ------------------------\n\n\n");
    printf("------------------------------------------------------------------------------\n");
    return 0;
}

int yyerror(char * msg)
{
	printf("错误:%s 在行号为:%d\n",msg, yylinenumber);
        return 0;
}


⌨️ 快捷键说明

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