一、实验目的:
运用YACC,针对给定的文法,构造一个语法分析器。给出实验方案,实施并描述结果。
二、实验预习提示
1、表达:针对5.5节中的calculator文法,设计输入和输出
2、观察:观察parsing table,解析parsing table.
3、模块间的衔接,如何同时使用lex 和 yacc
4、能力:是否有能力有工具完成一个分析器
5、比较:用工具和手工编写程序的比较
三、实验过程
(1)设计基于YACC的TINY词法分析器
(2)设计基于LEX的TINY语法分析器
(3)使用两个分析器分析算数文法
四、程序输入/输出示例
1、针对TINY语言给出 yacc的y文件的代码
%{#include <ctype.h>
#include<stdio.h>
#define MSDOS
int linecount;
extern int yylex();
extern int yyerror();
%}
%union{
char chr;
char str;
int integer;
float real;
double dbl;
}
%token number
%type expr number
%left ‘+’ ‘-’
%left '’ ‘/’
%right uminus
%%
lines: lines expr’\n’
{
printf(“line %d:%g\n”,linecount++,$2);
}
|lines’\n’
{
linecount++;
}
| ;
expr: expr’+'expr
{
KaTeX parse error: Can't use function '$' in math mode at position 2: =$̲1+$3; } |expr…=$1-$3;
}
|expr '’ expr
{
KaTeX parse error: Can't use function '$' in math mode at position 2: =$̲1*$3; } | exp…=$1/$3;
}
| ‘(’ expr ‘)’
{
KaTeX parse error: Can't use function '$' in math mode at position 2: =$̲2; } | '-' ex…=-$2;
}
| number;
%%
int yyerror(s)
char s;
{
fprintf(stderr,“syntactic error:%s\n”,s);
return 0;
}
2、给出.l文件的代码
%{
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define ture 1
#define false 0
#include “yacc.tab.h”
extern int lexverbose;
extern int linecount;
%}
digit [0-9]
letter [a-zA-Z]
%%
{digit}+ {
yylval.real=(float)atof(yytext);
if(lexverbose)
printf(“real:%g\n”,yylval.real);
return(number);
}
+ {
yylval.chr=yytext[0];
if(lexverbose)
printf(“opterator:%c\n”,yylval.chr);
return(’+’);
}
- {
yylval.chr=yytext[0];
if(lexverbose)
printf(“oprator:%c\n”,yylval.chr);
return(’-’);
}
* {
yylval.chr=yytext[0];
if(lexverbose)
printf(“oprator:%c\n”,yylval.chr);
return(’’);
}
/ {
yylval.chr=yytext[0];
if(lexverbose)
printf(“oprator:%c\n”,yylval.chr);
return(’/’);
}
“(” {
yylval.chr=yytext[0];
if(lexverbose)
printf(“separator:%c\n”,yylval.chr);
return(’(’);
}
“)” {
yylval.chr=yytext[0];
if(lexverbose)
printf(“separtor:%c\n”,yylval.chr);
return(’)’);
}
;
{
return(’;’);
}
\n {
printf(“line %d\n”,linecount);
/ linecount++; /
return(’\n’);
}
[ \t]+ {
printf(“lexical analyzer error\n”);
}
quit {
printf(“Bye!\n”);
exit(0);
}
%%
int yywrap()
{
return(1);
}
3、编译主函数main.c
#include"lex.yy.c"
#include"yacc.tab.c"
#include <stdlib.h>
#include <stdio.h>
int lexverbose=1;
extern int yyparse();
int main(int argc, char argv[])
{
extern FILE *yyin;
printf(“Compiling…!\n”);
if((yyin=fopen(“test.c”,“rt”))==NULL){
perror(“can not open file test.txt\n”) ;
exit(1);
}
if (yyparse()==1){
fprintf(stderr,“parser error\n”);
exit(1);
}
printf(“yyparse() completed successfully!\n”);
return 0;
}
五、程序思路
先设计基于YACC的TINY词法分析器,再设计基于LEX的TINY语法分析器,再设计主函数main.c编译后调用两个分析器分析算数文法