zoukankan      html  css  js  c++  java
  • 程序中,调用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]#
  • 相关阅读:
    POJ 1703 Find them, Catch them
    POJ 2236 Wireless Network
    POJ 2010 Moo University
    POJ 2184 Cow Exhibition
    POJ 3280 Cheapest Palindrome
    POJ 3009 Curling 2.0
    POJ 3669 Meteor Shower
    POJ 2718 Smallest Difference
    POJ 3187 Backward Digit Sums
    POJ 3050 Hopscotch
  • 原文地址:https://www.cnblogs.com/gaojian/p/3083662.html
Copyright © 2011-2022 走看看