3.6 二义文法的应用|3.7 分析器的生成器

3.6 二义文法的应用

二义文法的特点:

  • 二义文法不是LR文法

  • 简洁、自然

  • 可以用文法以外的信息来消除二义

  • 语法分析的效率高(基于消除二义后得到的分析表)

3.6.1 使用文法以外信息来解决分析动作冲突

二义文法 E * E + E | E * E | (E) | id
规定: *优先级高于+,两者都是左结合

3.7 分析器的生成器

3.7.1 分析器的生成器Yacc

分析器的生成器Yacc

3.7.2 用Yacc处理二义文法

简单计算器
输入一个表达式并回车,显示计算结果
也可以输入一个空白行

%{
# include  <ctype .h>
# include  <stdio.h >
# define YYSTYPE double /将栈定义为double类型 /
%}
 
%token  NUMBER
%left  ‘+’  ‘-’
%left  ‘*’  ‘/ ’
%right  UMINUS(一元减)
%% 

1、栈的精度为double,是为了存储文法符号的属性
2、记号的定义顺序为优先级顺序(逐渐升高);left代表左结合,right代表右结合

left左结合
right右结合

lines	 	: lines expr ‘\n’    {printf ( “%g \n”, $2 ) }
			| lines ‘\n’
			|  /* */
			;
expr		: expr ‘+’ expr 	{$$ = $1 + $3; }
			| expr ‘-’ expr	{$$ = $1 - $3; }
			| expr ‘*’ expr	{$$ = $1 * $3; }
			| expr ‘/ ’ expr 	{$$ = $1 / $3; }
			| ‘(’ expr ‘)’		{$$ = $2; }
			| ‘-’ expr  %prec UMINUS	{$$ = -$2; }
			| NUMBER
			;
			
%%

-5+10看成是-(5+10), 还是(-5)+10? 取后者
“%prec UMINUS”的意义是调整下前面符号的优先级

yylex ( ) {
		int c;
		while ( ( c = getchar ( ) ) == ‘  ’ );
		if ( ( c == ‘.’ ) | | (isdigit (c) ) ) {
			ungetc (c, stdin);
			scanf ( “% lf ”,  &yylval);
			return  NUMBER;
		}
		return c;
}

Yylex()是词法分析程序

image

posted @ 2021-05-10 10:37  辛勤的小码农^-^  阅读(162)  评论(0)    收藏  举报