zoukankan      html  css  js  c++  java
  • 使用bison和flex工具[zz]

     这里有一个使用bison建立一个简单的计算器的例子:
    http://www.cs.berkeley.edu/~maratb/cs164/bison.html

    使用bison和flex工具学习编译原理,远比单独看书然后自己编写一些程序生动的多。这样你就不会在那些复杂的字符处理,正则表达式的处理上浪费精力,最后费尽心力,却没有结果,失去了学习的兴趣。

    我 这里有一个简单的计算器的程序,可以实现加、减、乘、除运算,并支持括号的处理和26个字母作为变量。以前自己使用后缀表达式方式写过一个这样的程序,单 单中缀表达式改为后缀表达式就是几百行的代码,反正自己现在还是不知道怎么处理里面复杂的堆栈的(我用了STL的List实现)。



    词法处理文件calc.lex内容如下:
    %{
        /*
         *  一个简单计算器的Lex词法文件
         */
        #include <stdlib.h>
       
        void yyerror(char*);
        #include "calc.tab.h"
    %}
    %%
        /* a-z为变量 */
    [a-z]    {
            yylval = *yytext - 'a';
            return VARIABLE;
        }
        /* 整数 */
    [0-9]+    {
            yylval = atoi(yytext);
            return INTEGER;
        }
        /* 运算符 */
    [-+()=\*\n]    {return *yytext;}
        /* 空白被忽略 */
    [ /t]    ;
        /* 其他字符都是非法的 */
    .    yyerror("无效的输入字符");
    %%
    int    yywrap(void)
    {
        return 1;
    }
    词法处理的目标就是区分出来每个成员到底是什么,这里有两种 INTEGER和VARIABLE。只要区分出来各个成分词法分析的任务就完成了。



    语法处理文件calc.y内容如下:
    %token    INTEGER VARIABLE
    %left    '+' '-'
    %left    '*' '/'
    %{
        #include <stdio.h>
        void yyerror(char*);
        int yylex(void);
        int sym[26];
    %}
    %%
    program:
        program statement '\n'
        |
        ;
    statement:
         expr    {printf("%d\n", $1);}
         |VARIABLE '=' expr    {sym[$1] = $3;}
         ;
    expr:
        INTEGER
        |VARIABLE{$$ = sym[$1];}
        |expr '+' expr    {$$ = $1 + $3;}
        |expr '-' expr    {$$ = $1 - $3;}
        |expr '*' expr    {$$ = $1 * $3;}
        |expr '/' expr    {$$ = $1 / $3;}
        |'('expr')'    {$$ = $2;}
        ;
    %%
    void yyerror(char* s)
    {
        fprintf(stderr, "%s\n", s);
    }
    int main(void)
    {
        printf("A simple calculator.\n");
        yyparse();
        return 0;
    }
    语法分析文件的写法就是将BNF表达式描述一下即可,规则随着条目逐渐细化,变成了可以理解的内容。这里不用管如何实现这些语法的分析,只是需要告知如何构建这些语法。



    编译命令如下:
    >bison -d calc.y
    >flex calc.lex
    >gcc calc.tab.c lex.yy.c -o calc

    ------------------------------------------------

    yyparse 是bison生成的函数,用于解析语法,同时yylex是flex生成的函数,用于解析词法,bison生成的函数调用yylex不断处理,处理出来适合的表达式,之后计算.

  • 相关阅读:
    c# 泛型总结
    透过字节码分析java基本类型数组的内存分配方式。
    c#索引器
    redis在asp.net 中的应用
    Unity3D shaderLab
    Unity3d Asset Store 打不开
    C# 类型转换的开销
    [转]权重算法
    Coroutine的原理以及实现
    在Unity3D里使用WinForm
  • 原文地址:https://www.cnblogs.com/linucos/p/2704185.html
Copyright © 2011-2022 走看看