用Yacc实现语法分析器

您所在的位置:网站首页 编译原理文法的句子 用Yacc实现语法分析器

用Yacc实现语法分析器

2024-07-11 00:46| 来源: 网络整理| 查看: 265

 用Yacc实现语法分析器

 

一、实验目的

掌握语法分析器的构造原理,掌握Yacc的编程方法。

 

二、实验内容

用Yacc编写一个语法分析程序,使之与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。

program      → block

block     →   { stmts }

stmts     → stmt stmts | e

       stmt       →   id= expr ;

                        |      if ( bool ) stmt

                            |      if ( bool) stmt else stmt

|      while (bool) stmt

|      do stmt while (bool ) ;

|      break ;

|      block

bool      → expr < expr

|     expr expr

|     expr >= expr

|     expr

expr      → expr + term

|     expr - term

|     term

term      → term * factor

 |   term / factor

|     factor

factor     → ( expr ) | id| num 

 

 

三、实验步骤及结果

实验环境:unix

实验结果:按归约的先后顺序显示每次归约时所使用的产生式。

部分代码:

用于产生flex输入的代码

View Code Test.l:[a-zA-Z_][a-zA-Z_0-9]* {return ID;} [0-9]+\.[0-9]+ {return REAL;} [0-9]+ {return NUM;} "||" {return OR;} "&&" {return AND;} "|" {return '|';} "&" {return '&';} "=" {return GE;} ">" {return '>';} "!=" {return NE;} "=" { return '=';} "==" {return EQ;} "\+" {return '+';} "\-" {return '-';} "\*" {return '*';} "\/" {return '/';} "(" {return '(';} ")" {return ')';} ";" {return ';';} "{" {return '{';} "}" {return '}';} "[" {return '['; } "]" {return ']';} Test.y:rel : expr '' expr { printf("rel-->expr>expr\n"); } | expr { printf("rel-->expr\n"); } ; expr : expr '+' term { printf("expr-->expr+term\n"); } | expr '-' term { printf("expr-->expr-term\n"); } | term { printf("expr-->term\n"); } ; term : term '*' unary { printf("term-->term*unary\n"); } | term '/' unary { printf("term-->term/unary\n"); } | unary { printf("term-->unary\n"); } ; unary : '!' unary { printf("unary-->!unary\n"); } | '-' unary %prec UMINUS{ printf("unary-->-unary\n"); } | factor { printf("unary-->factor\n"); } ; factor : '(' bool ')' { printf("factor-->(bool)\n"); } | loc { printf("factor-->loc\n"); } | NUM { printf("factor-->num\n"); } | REAL { printf("factor-->real\n"); } | TRUE { printf("factor-->true\n"); } | FALSE { printf("factor-->false\n"); }

Flex生成代码:

View Code Test.l:[a-zA-Z_][a-zA-Z_0-9]* {return ID;} [0-9]+\.[0-9]+ {return REAL;} [0-9]+ {return NUM;} "||" {return OR;} "&&" {return AND;} "|" {return '|';} "&" {return '&';} "=" {return GE;} ">" {return '>';} "!=" {return NE;} "=" { return '=';} "==" {return EQ;} "\+" {return '+';} "\-" {return '-';} "\*" {return '*';} "\/" {return '/';} "(" {return '(';} ")" {return ')';} ";" {return ';';} "{" {return '{';} "}" {return '}';} "[" {return '['; } "]" {return ']';} Test.y:rel : expr '' expr { printf("rel-->expr>expr\n"); } | expr { printf("rel-->expr\n"); } ; expr : expr '+' term { printf("expr-->expr+term\n"); } | expr '-' term { printf("expr-->expr-term\n"); } | term { printf("expr-->term\n"); } ; term : term '*' unary { printf("term-->term*unary\n"); } | term '/' unary { printf("term-->term/unary\n"); } | unary { printf("term-->unary\n"); } ; unary : '!' unary { printf("unary-->!unary\n"); } | '-' unary %prec UMINUS{ printf("unary-->-unary\n"); } | factor { printf("unary-->factor\n"); } ; factor : '(' bool ')' { printf("factor-->(bool)\n"); } | loc { printf("factor-->loc\n"); } | NUM { printf("factor-->num\n"); } | REAL { printf("factor-->real\n"); } | TRUE { printf("factor-->true\n"); } | FALSE { printf("factor-->false\n"); }

Yacc生成部分代码:

View Code #line 1334 "y.tab.c" yyvsp -= yylen; yyssp -= yylen; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3