Chinaunix首页 | 论坛 | 博客
  • 博客访问: 652600
  • 博文数量: 151
  • 博客积分: 3498
  • 博客等级: 中校
  • 技术积分: 1570
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-28 18:10
文章分类

全部博文(151)

文章存档

2014年(12)

2013年(17)

2012年(17)

2011年(5)

2010年(12)

2009年(2)

2007年(26)

2006年(22)

2005年(38)

分类: LINUX

2007-09-27 22:41:58

其实一直都不了解词法分析和语法分析是干什么的,很偶然的机会,接触到了词法分析和语法分析这个东东。在项目中因为要完成字符串中很多同名的变量到相应值的替换,本来要实现的功能也不是很复杂,但是有人提议说可以用词法分析这个工具来做替换,所以偶就开始调查了。
      刚开始也不知道FLEX和BISON到底能干什么,他们之间是什么关系。与我要用它来完成的功能如何实现,其实都不知道。然后上网找找资料,发现BISON MANUAL讲得比较详细。所以就认真的看了,看完后算是有了点基础,知道BISON干什么了,也知道它是如何去做的。
     在BISON MANUAL中,关于语法分析器算法(shift/reduce 移进/规约)的了解比较重要,还有就是语法规则的左递归,右递归和相互递归。最后无论如何都要理解分析器,知道分析器的各个状态。状态机在没办法搞清楚GRAMMER RULE如何工作的时候,能够提供非常好的跟踪方式。
    下面就从一个修改的例子开始。
     地址在:http://www.ibm.com/developerworks/cn/linux/l-flexbison.html
     名称:使用 Flex 和 Bison 更好地进行错误处理

1)如何解决输入问题
   一个是修改yylex这个函数,默认的yyin是stdin,所以修改了这个函数后就可以让你的输入来自file,也可以来自stdin.
   另外一个就是修改YY_INPUT这个MACRO,让你决定buf的内容从哪儿读出.此处是要匹配"policer todo{CT_MEDIA_NUM}"这个字符串中的{CT_MEDIA_NUM}.而且要替换成另外的值.
   #undef   YY_INPUT
   #define YY_INPUT(buf,result,max_size)  {\
    result = GetNextChar(buf, max_size); \
    if (  result <= 0  ) \
      result = YY_NULL; \
    }

static char tmpbuf[256]="\"policer todo{CT_MEDIA_NUM}\"";
extern
int GetNextChar(char *b, int maxBuffer) {
        int frc;    
    static int cntDummy=0;
    if(cntDummy>0)return 0;
    
    strcpy( b, tmpbuf);
    cntDummy++;
   
    frc =strlen(b);
    printf("out:%s\n",b);   
        return frc;
}

2)如何解决语法规则
    追加一个类型mytype,因为作为一个组被使用的时候,必须是数值类型.
    %type      mytype
   然后declare 3个token ,分别是{,}和".
   %token LCYC
   %token RCYC
   %token IN
  
  program
    : statement SEMICOLON program
    | IN mytype IN
    | text
    ;

  mytype
     : LCYC mytype RCYC
     {
        $$=$2;
        printf("haha,get out:%d\n",$$);
     }
     | VALUE { $$=$1; printf("VALUE:%d\n",$$); }
     | IDENTIFIER {  $$=GetCmdVal($1); }
     | program mytype       ####-####-####--使用了相互递归,解决问题.
     ;
    
  text:/*empty string match*/
      |IDENTIFIER
      ;
    上面的IDENTIFIER ,VALUE 是终止型,而mytype是非终止型.
    一个终结符(terminal symbol)(也被称做符号类型(token type)代表了一类从构造上等价的记号.
    一个非终结符(noterminal symbol)代表一类从构造上等价的组.

3)如何产生词法分析规则
  当在字符中出现如下字符时,返回相应的token. 

[0-9]+  {
         /* 0-9 number of several */
        printf("digital find:%s\n",yytext);
        yylval.value = strtol(yytext,NULL,10);
        printf("yylval.value =%d\n", yylval.value );
        return VALUE;
        }   
[_a-zA-Z][_a-zA-Z0-9]*   {
           /*Act_09 number and alpha*/
       printf("text find:%s\n",yytext);
           yylval.string = malloc(strlen(yytext)+1);
           strcpy(yylval.string, yytext);
           return IDENTIFIER;
         }
"{"       {printf("find:%s\n",yytext); return LCYC; }
"}"       {printf("find:%s\n",yytext); return RCYC; }
"\""       {printf("find:%s\n",yytext); return IN; } 

4)辅助处理的函数和结构
    定义一个结构体
    typedef struct _CMD_TYPE {
        char    name[256];
        int     value;
    } CmdType;
    声明变量
    static CmdType  cmdType[2]={{"CT_MEDIA_NUM",4},
                         {"CB_SR",102}
                         };
     调用函数返回替换的VALUE.
     extern
     int GetCmdVal( char *varname ){
         int i=0;
     for(i = 0 ;i< 2;i++)
    {
            if( 0 == strcmp(varname,cmdType[i].name) )
            return cmdType[i].value ;
    }
    return -1;
      }
5)查看输出结果
   输出结果默认是stdout,可以修改yyout,让它输出到file.
   本实例的输出将变成: policer todo4
  
附件是修改过的工程文件
文件:ccalc-m.rar
大小:28KB
下载:下载
阅读(2822) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~