请教Parser Generator 开发工具中关于Lex和Yacc的问题

 我来答
huanglenzhi
2015-04-14 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数: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();
  }
转载
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式