• 程序中,调用Bison和Flex结合的小例子


    网上的很多程序,对初次接触Bison和Flex的人而言,都有点复杂,看最简单的例子更好些:

    http://stackoverflow.com/questions/1920604/how-to-make-yy-input-point-to-a-string-rather-than-stdin-in-lex-yacc-solaris

    我稍微修改一下,说说自己的理解,也作为一个备忘:

    Flex程序:

     1 [root@lex total]# cat lexer.l
     2 %{
     3 
     4 #include "y.tab.h"
     5 #include <stdio.h>
     6 
     7 
     8 #undef YY_INPUT
     9 #define YY_INPUT(b,r,s) readInputForLexer(b,&r,s)
    10 
    11 %}
    12 
    13 DIGIT   [0-9]
    14 %%
    15 
    16 \+      { printf("got plus\n"); return FUNCTION_PLUS; }
    17 \-      { printf("got minus\n"); return FUNCTION_MINUS; }
    18 {DIGIT}* { printf("got number\n"); return NUMBER; }
    19 %%
    20 
    21 
    22 void yyerror(char* s) {
    23     printf("error %s \n",s);
    24 }
    25 
    26 int yywrap() {
    27     return -1;
    28 }
    29 [root@lex total]# 

    这个程序说明了数字、加号、减号的识别规则

    同时,为了让yylex()可以读入字符串而不是读入文件,覆盖了 YY_INPUT。

    Bison(Yacc)程序:

     1 [root@lex total]# cat parser.y
     2 %{
     3 #include <stdio.h>
     4 extern void yyerror(char* s);
     5 extern int yylex();
     6 extern int readInputForLexer(char* buffer,int *numBytesRead,int maxBytesToRead);
     7 %}
     8 
     9 %token FUNCTION_PLUS FUNCTION_MINUS NUMBER
    10 
    11 %%
    12 
    13 expression:
    14     NUMBER FUNCTION_PLUS NUMBER { printf("got plus expression!  Yay!\n"); }
    15     |
    16     NUMBER FUNCTION_MINUS NUMBER { printf("got minus expression! Yay!\n");}
    17     ;
    18 %%
    19 [root@lex total]# 

    这个程序说明了两个表达式: 加法(NUMBER FUNCTION_PLUS NUMBER) 和 减法(NUMBER FUNCTION_MINUS NUMBER)。

    主程序:

     1 [root@lex total]# cat myparser.c
     2 #include <stdio.h>
     3 #include <string.h>
     4 
     5 int yyparse();
     6 int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead );
     7 
     8 static int globalReadOffset;
     9 // Text to read:
    10 static const char *globalInputText = "23 - 5";
    11 
    12 int main() {
    13     globalReadOffset = 0;
    14     yyparse();
    15     return 0;
    16 }
    17 
    18 int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) {
    19     int numBytesToRead = maxBytesToRead;
    20     int bytesRemaining = strlen(globalInputText)-globalReadOffset;
    21     int i;
    22     if ( numBytesToRead > bytesRemaining ) { numBytesToRead = bytesRemaining; }
    23     for ( i = 0; i < numBytesToRead; i++ ) {
    24         buffer[i] = globalInputText[globalReadOffset+i];
    25     }
    26     *numBytesRead = numBytesToRead;
    27     globalReadOffset += numBytesToRead;
    28     return 0;
    29 }
    30 [root@lex total]# 

    在主程序中,为了能够让 yylex读取字符串,声明了 readInputForlexer函数。

    根据YACC的约定,yyparse()会去调用 yylex()。而yylex()调用 readInputForLexer,一次一次地返回给yyparse。

    编译和执行:

    yacc -d parser.y
    lex lexer.l
    gcc -o myparser *.c
    ./myparser

    执行结果:

    [root@lex total]# ./myparser
    got number
     got minus
     got number
    got minus expression! Yay!
    [root@lex total]#
  • 相关阅读:
    YUM软件管理
    RPM软件包管理
    Linux系统启动详解
    Linux命令行文本处理工具
    Linux多命令协作:管道及重定向
    Linux网络基础配置
    网络基础
    Linux扩展权限
    Linux权限机制
    Linux用户基础
  • 原文地址:https://www.cnblogs.com/gaojian/p/3083662.html
Copyright © 2020-2023  润新知