请教Parser Generator 开发工具中关于Lex和Yacc的问题
1个回答
2015-04-14 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
向TA提问 私信TA
知道合伙人数码行家
采纳数:117538
获赞数:517195
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。
向TA提问 私信TA
关注
展开全部
本篇文章主要介绍了"请教Parser Generator 开发工具中关于Lex和Yacc的问题 ",主要涉及到请教Parser Generator 开发工具中关于Lex和Yacc的问题 方面的内容,对于请教Parser Generator 开发工具中关于Lex和Yacc的问题 感兴趣的同学可以参考一下。
注释:expression为double类型,stringexp为char *类型。
目的:实现计算器和字符串的混合输入模式
状态:简单的计算器以及语法expression ADD stringexp(例如:3+4+"sdfe")已实现
问题:char *字符串类型本身的结合以及其和double计算器类型的结合即stringexp ADD stringexp和stringexp ADD expression语法未实现。多方测试,觉得是其语法分析构造的问题,但却一直无法找到根本原因。故此希望大家能够给我指点,谢谢
关键:标记1,2加粗标有下划线的代码段构造问题,如果撤销注释,则测试显示无法将STRING的值传递给最终的statment中。
代码如下:
///////////////////////头文件ch3hdr.h
#define NSYMS 20
struct symtab{
char *name;
int type;
double (*funcptr)();
double value;
char *str;
}symtab[NSYMS];
struct symtab *symlook();
//////////////////////词法分析mylexer.l
%{
#include "myparser.h"
#include <stdio.h>
#include <stdlib.h>
#include "ch3hdr.h"
#include <math.h>
%}
%%
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
yylval.dval=atof(yytext);//itoa
return NUMBER;}
[ \t] ;
"+" {return ADD;}
"-" {return DEC;}
"*" {return MUL;}
"/" {return DIV;}
"(" {return LPAR;}
")" {return RPAR;}
"=" {return QUE;}
"," {return COMMA;}
"$" {return 0;}
//[\"]([A-Za-z0-9 ]*)[\"] {
[\"]([^\"]*)[\"] {
yylval.sval=yytext;
return STRING;}
[A-Za-z][A-Za-z0-9]* {
struct symtab *sp=symlook(yytext);
yylval.symp=sp;
return NAME;}
[ .\n] return yytext[0];
%%
////////////////////////语法分析myparser.y
%{
#include "mylexer.h"
#include "ch3hdr.h"
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXBUFF 100
%}
%union{
double dval;
char *sval;
struct symtab *symp;
}
%token <symp> NAME
%token <dval> NUMBER
%token <sval> STRING
%token QUE ADD DEC MUL DIV LPAR RPAR COMMA
%left ADD DEC
%left MUL DIV
%nonassoc UMINUS
%type <dval> expression
%type <sval> stringexp
%%
statment_list: statment '\n'
| statment_list statment '\n'
;
statment: NAME QUE expression {$1->value=$3; $1->type=1;printf("%s is %g\n",$1->name,$3);}
| NAME QUE stringexp {$1->value=0;$1->str=strdup($3);$1->type=2;printf("string %s is %s\n",$1->name,$1->str);}
| expression {printf("expression=%g\n",$1);}
| stringexp {printf("stringexp=%s\n",$1);}
;
stringexp: expression ADD stringexp {$$=(char *)malloc(sizeof(char *)MAXBUFF);sprintf($$,"%g%s",$1,$3);}
// | stringexp ADD stringexp {$$=(char *)malloc(sizeof(char *)MAXBUFF);sprintf($$,"%s%s\n",$1,$3);}------------1
// | stringexp ADD expression {$$=(char *)malloc(sizeof(char *)MAXBUFF);}---------------------------------------------2
| STRING {strrev(strnset(strrev(strnset($1,' ',1)),' ',1));sprintf($$,"%s",$1);}
;
expression: expression ADD expression {$$ = $1 + $3;}
| NUMBER {$$=$1;}
| expression DEC expression {$$ = $1 - $3;}
| expression MUL expression {$$ = $1 * $3;}
| expression DIV expression {
if($3=0.0)
yyerror("Divid by zero");
else
$$ = $1 / $3;
}
| DEC expression %prec UMINUS {$$ = - $2;}
| LPAR expression RPAR {$$ = $2;}
| NAME {$$ = $1->value;}
| NAME LPAR expression RPAR {
if($1->funcptr)
$$=($1->funcptr)($3);
else{
printf("%s not a function\n",$1->name);
$$=0.0;
}
}
| NAME LPAR expression COMMA expression RPAR {
if($1->funcptr)
$$=($1->funcptr)($3,$5);
else{
printf("%s not a function\n",$1->name);
$$=0.0;
}
}
;
%%
struct symtab * symlook(char *s)
{
struct symtab *sp;
for(sp=symtab;sp<&symtab[NSYMS];sp++)
{
if(sp->name && !strcmp(sp->name,s))
return sp;
if(!sp->name)
{
sp->name=strdup(s);
return sp;
}
}
yyerror("Too many symbols");
exit(1);
}
addfunc(char *name,double (*func)())
{
struct symtab *sp=symlook(name);
sp->funcptr=func;
}
main(void)
{
extern double sqrt(),exp(),log(),atan2(),fmod();
addfunc("sqrt",sqrt);
addfunc("exp",exp);
addfunc("log",log);
addfunc("atan2",atan2);
addfunc("fmod",fmod);
yyparse();
}
转载
注释:expression为double类型,stringexp为char *类型。
目的:实现计算器和字符串的混合输入模式
状态:简单的计算器以及语法expression ADD stringexp(例如:3+4+"sdfe")已实现
问题:char *字符串类型本身的结合以及其和double计算器类型的结合即stringexp ADD stringexp和stringexp ADD expression语法未实现。多方测试,觉得是其语法分析构造的问题,但却一直无法找到根本原因。故此希望大家能够给我指点,谢谢
关键:标记1,2加粗标有下划线的代码段构造问题,如果撤销注释,则测试显示无法将STRING的值传递给最终的statment中。
代码如下:
///////////////////////头文件ch3hdr.h
#define NSYMS 20
struct symtab{
char *name;
int type;
double (*funcptr)();
double value;
char *str;
}symtab[NSYMS];
struct symtab *symlook();
//////////////////////词法分析mylexer.l
%{
#include "myparser.h"
#include <stdio.h>
#include <stdlib.h>
#include "ch3hdr.h"
#include <math.h>
%}
%%
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
yylval.dval=atof(yytext);//itoa
return NUMBER;}
[ \t] ;
"+" {return ADD;}
"-" {return DEC;}
"*" {return MUL;}
"/" {return DIV;}
"(" {return LPAR;}
")" {return RPAR;}
"=" {return QUE;}
"," {return COMMA;}
"$" {return 0;}
//[\"]([A-Za-z0-9 ]*)[\"] {
[\"]([^\"]*)[\"] {
yylval.sval=yytext;
return STRING;}
[A-Za-z][A-Za-z0-9]* {
struct symtab *sp=symlook(yytext);
yylval.symp=sp;
return NAME;}
[ .\n] return yytext[0];
%%
////////////////////////语法分析myparser.y
%{
#include "mylexer.h"
#include "ch3hdr.h"
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXBUFF 100
%}
%union{
double dval;
char *sval;
struct symtab *symp;
}
%token <symp> NAME
%token <dval> NUMBER
%token <sval> STRING
%token QUE ADD DEC MUL DIV LPAR RPAR COMMA
%left ADD DEC
%left MUL DIV
%nonassoc UMINUS
%type <dval> expression
%type <sval> stringexp
%%
statment_list: statment '\n'
| statment_list statment '\n'
;
statment: NAME QUE expression {$1->value=$3; $1->type=1;printf("%s is %g\n",$1->name,$3);}
| NAME QUE stringexp {$1->value=0;$1->str=strdup($3);$1->type=2;printf("string %s is %s\n",$1->name,$1->str);}
| expression {printf("expression=%g\n",$1);}
| stringexp {printf("stringexp=%s\n",$1);}
;
stringexp: expression ADD stringexp {$$=(char *)malloc(sizeof(char *)MAXBUFF);sprintf($$,"%g%s",$1,$3);}
// | stringexp ADD stringexp {$$=(char *)malloc(sizeof(char *)MAXBUFF);sprintf($$,"%s%s\n",$1,$3);}------------1
// | stringexp ADD expression {$$=(char *)malloc(sizeof(char *)MAXBUFF);}---------------------------------------------2
| STRING {strrev(strnset(strrev(strnset($1,' ',1)),' ',1));sprintf($$,"%s",$1);}
;
expression: expression ADD expression {$$ = $1 + $3;}
| NUMBER {$$=$1;}
| expression DEC expression {$$ = $1 - $3;}
| expression MUL expression {$$ = $1 * $3;}
| expression DIV expression {
if($3=0.0)
yyerror("Divid by zero");
else
$$ = $1 / $3;
}
| DEC expression %prec UMINUS {$$ = - $2;}
| LPAR expression RPAR {$$ = $2;}
| NAME {$$ = $1->value;}
| NAME LPAR expression RPAR {
if($1->funcptr)
$$=($1->funcptr)($3);
else{
printf("%s not a function\n",$1->name);
$$=0.0;
}
}
| NAME LPAR expression COMMA expression RPAR {
if($1->funcptr)
$$=($1->funcptr)($3,$5);
else{
printf("%s not a function\n",$1->name);
$$=0.0;
}
}
;
%%
struct symtab * symlook(char *s)
{
struct symtab *sp;
for(sp=symtab;sp<&symtab[NSYMS];sp++)
{
if(sp->name && !strcmp(sp->name,s))
return sp;
if(!sp->name)
{
sp->name=strdup(s);
return sp;
}
}
yyerror("Too many symbols");
exit(1);
}
addfunc(char *name,double (*func)())
{
struct symtab *sp=symlook(name);
sp->funcptr=func;
}
main(void)
{
extern double sqrt(),exp(),log(),atan2(),fmod();
addfunc("sqrt",sqrt);
addfunc("exp",exp);
addfunc("log",log);
addfunc("atan2",atan2);
addfunc("fmod",fmod);
yyparse();
}
转载
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询