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

📄 简单的yacc程序.txt

📁 目的:通过编写简单的YACC程序熟悉YACC词法分析工具的基本用法
💻 TXT
字号:
程序源代码:
/*Lex(toyacc.lex)用于产生YACC所需的单词*
final [\+\t\n]                                          /* 正则式定义 */
ws    [final]+
letter [A-Za-z]
digit [0-9]
num   {digit}+ 
id    {letter}({letter}|{digit})*
%%

{ws}   {}                                           /* 向YACC输出单词流*/
if     {inif=1;return(IF);}  
then   {return(THEN);}
else   {state=abs(state-1);return(ELSE);}                  /*if中条件为布尔0,state取反*/
{id}   {yylval.str=strdup (yytext); return(ID);}               
{num}  {yylval.str=strdup (yytext); return(NUM);}
":="   {return(FUZHI);}
"<"    {yylval.intvar = 1;return(COMP);}                 /*返回比较符*/
"<="   {yylval.intvar = 2;return(COMP);}
"="    {yylval.intvar = 3;return(COMP);}
"<>"   {yylval.intvar = 4;return(COMP);}
">"    {yylval.intvar = 5;return(COMP);}
">="   {yylval.intvar = 6;return(COMP);}
";"    {return(ENDOFC);}
"+"    {return('+');}
"*"    {return('*');}
"-"    {return('-');}
%%
 void readfile()
{
 yyin=yylex();
}
int yywrap()
{
  return 1;
}

/*YACC做PASCAL语法分析*/
%{
  #include<stdio.h>
  #include<ctype.h>
  #include <string.h>
  typedef char* string;
  char* idnames[20];  
  int idvalues[20];  
  int total=0,found=0,a,inif=0,state=0;                      /*total 总标识符个数,state  if语句是否成立*/
%}
%union {
   int intvar;                                           /*定义yylex与yacc之间接口变量的值用于传回数char *str                      字和字符串。*/
  }
%token IF THEN ELSE ID NUM FUZHI COMP ENDOFC      /*定义标识符*/
%left '+'
%left '*'
%right UMINUS

%%
 
lines : ifstat ENDOFC  {inif=0;}                            /*当一个if语句结束的时候,将标志变量复原*/
      | idexpr ENDOFC  
	  | lines lines
	  ;
ifstat : IF statexpr THEN idexpr ELSE idexpr                   /*if-else语句的生成式*/
       | IF statexpr THEN idexpr
       ;
 statexpr : expr PANDUAN expr {
							  state=0;                  /*根据传回的判断符号和实际情况置 state值*/
							  if ($2.intvar==1 && $1.intvar==$3.intvar) state=1;
							  else if ($2.intvar==2 && $1.intvar<$3.intvar) state=1;
							  else if ($2.intvar==3 && $1.intvar<=$3.intvar) state=1;
							  else if ($2.intvar==4 && $1.intvar!=$3.intvar) state=1;
							  else if ($2.intvar==5 && $1.intvar>$3.intvar) state=1;
							  else if ($2.intvar==6 && $1.intvar>=$3.intvar) state=1;
							} ;
/*赋值语句的生成式*/
idexpr : ID FUZHI expr  { 
                          if (inif==0 || (inif==1 && state==1)){ //如果赋值语句不在if语句内,或者是一个为真的if语句内
							found=0;
							for(a=1;a<=total;a++)           // 标识符存在,直接赋值
     	  				    if (strcmp($1.str,idnames[a])==0){
     						    found=1;
     						    idvalues[a]=$3.intvar;
     						}
     						if (found==0) {                //如不存在,添加进符号表
     						  total++;
     						  idnames[total]=strdup($1.str);
     						  idvalues[total]=$3.intvar;
     						}
						  }
   				        }  ;
/*计算式,包含标识符以及数字的生成式*/
expr : expr'+'expr              {$$.intvar=$1.intvar+$3.intvar;}  
     | expr'*'expr              {$$.intvar=$1.intvar*$3.intvar;}  
     | '('expr')'               {$$.intvar=$2.intvar;}   
     |'-'expr %prec UMINUS      {$$.intvar=-$2.intvar;}  
     | NUM                      {$$.intvar=atoi(yylval.str);}  
     |ID                        {
     								found=0;                     
     								for(a=1;a<=total;a++)
     								  if (strcmp($1.str,idnames[a])==0){
     								    found=1;
     								    $$.intvar=idvalues[a];
     								  }
     								if (found==0) {
     								  total++;
     								  idnames[total]=strdup($1.str);
     								  $$.intvar=0;
     								  idvalues[total]=0;
     								}}    ; 
%%
#include"royacc.c"                                            /*引入lex中的分析结果*/
main(){ 
  yyparse();                                             
  printf("NO error!\n");  
  printf("%d identifiers totally:",total);
  for(a=1;a<=total;a++) printf("Idname: %s , Value: %d\n",idnames[a],idvalues[a]);
}
程序输出测试:
输入:x:=1;
y:=x+1;
if y>x then z=y else z=x;
输出:
      NO error!
3 identifiers totally: X:1
Y:2
                Z:2

⌨️ 快捷键说明

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