概述
[educoder] 用YACC(BISON)生成语法分析和翻译器
第一关
/* 逆波兰符号计算器 */
/* 功能:能够计算出合法的后缀表达式的值,包括加法、减法、乘法、除法、乘方、取反等运算 */
/* 说明:在下面的begin和end之间添加代码,加油吧! */
/* 提示: */
%{
#include <ctype.h>
#include <stdio.h>
#include <math.h>
int yylex (void);
void yyerror (char const *);
%}
%define api.value.type {double}
%token NUM
%%
/* Grammar rules and actions follow.
*/
input:
%empty
| input line
;
line:
'n'
| exp 'n'
{ printf ("%.10gn", $1); }
;
exp:
NUM
{ $$ = $1; }
/* begin: add your code */
| exp exp '+'
{$$ = $1 + $2;}
| exp exp '-'
{$$ = $1 - $2;}
| exp exp '*'
{$$ = $1 * $2;}
| exp exp '/'
{$$ = $1 / $2;}
| exp exp '^'
{$$ = pow($1, $2);}
| exp 'n'
{$$ = -$1;}
/* end: add your code */
;
%%
/* The lexical analyzer returns a double floating point
number on the stack and the token NUM, or the numeric code
of the character read if not a number.
It skips all blanks
and tabs, and returns 0 for end-of-input.
*/
int yylex (void)
{
int c;
/* Skip white space.
*/
while ((c = getchar ()) == ' ' || c == 't')
continue;
/* Process numbers.
*/
if (c == '.' || isdigit (c))
{
ungetc (c, stdin);
scanf ("%lf", &yylval);
return NUM;
}
/* Return end-of-input.
*/
if (c == EOF)
return 0;
if (c == '!')
return 0;
/* Return a single char.
*/
return c;
}
int main (int argc, char** argv)
{
return yyparse();
}
/* Called by yyparse on error.
*/
void yyerror (char const *s)
{
fprintf (stderr, "%sn", s);
}
;
第二关
/* 后缀转中缀 */
/* 功能:后缀表达式转换成中缀表达式,包括加法、减法、乘法、除法等运算 */
/* 说明:在下面的begin和end之间添加代码,加油吧! */
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifndef YYSTYPE
#define YYSTYPE char*
#endif
char idStr[50];
char numStr[50];
int yylex() ;
extern int yyparse() ;
FILE* yyin;
void yyerror(const char* s);
%}
%token ADD
%token MUL
%token SUB
%token DIV
%token LB
%token RB
%token NUMBER
%token ID
%left ADD MUS
%left MUL DIV
%right UMINUS
%%
lines : lines expr {printf("%sn",$2);}
| lines
|
;
/* begin: add your code*/
expr
: expr expr ADD { $$ = (char *)malloc(200*sizeof(char)); strcpy($$,"("); strcat($$,$1); strcat($$,"+"); strcat($$,$2);
strcat($$,")"); }
| expr expr SUB { $$ = (char *)malloc(200*sizeof(char)); strcpy($$,"("); strcat($$,$1); strcat($$,"-"); strcat($$,$2); strcat($$,")"); }
| expr expr MUL { $$ = (char *)malloc(200*sizeof(char)); strcpy($$,"("); strcat($$,$1); strcat($$,"*"); strcat($$,$2); strcat($$,")"); }
| expr expr DIV { $$ = (char *)malloc(200*sizeof(char)); strcpy($$,"("); strcat($$,$1); strcat($$,"/"); strcat($$,$2); strcat($$,")"); }
| SUB expr %prec UMINUS { strcpy($$,"-"); strcat($$,$2); }
| NUMBER
{ $$ = (char *)malloc(200*sizeof(char)); strcpy($$,$1); }
| ID
{ $$ = (char *)malloc(200*sizeof(char)); strcpy($$,$1); }
;
/* end: add your code */
;
%%
// programs section
int yylex()
{
char t;
while(1){
t = getchar();
if(t==' ' || t =='t'|| t == 'n')
{}
else if(t == '+'){
return ADD;
}
else if(t == '*'){
return MUL;
}
else if(t == '-'){
return SUB;
}
else if(t == '/'){
return DIV;
}
else if(t>='0'&&t<='9'){
int ti = 0;
while (t>='0'&&t<='9'){
numStr[ti]=t;
t = getchar();
ti++;
}
numStr[ti] = '