• 程序中,调用Bison和Flex结合的小例子(语法分析中处理数据)


    接着前面的 <程序中,调用Bison和Flex结合的小例子> 那一篇,再来整点新东西:

     http://www.cnblogs.com/gaojian/archive/2013/05/17/3083662.html

    我想,实际的工作中,绝对不会像逆波兰式计算器那样简单,直接就在语法分析器里完成计算。

    常常需要构造一颗语法树,然后把它传出来!例如各种数据库系统处理SQL文就是这样子。

    上程序:

     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 #ifndef YYSTYPE
    12 #define YYSTYPE int
    13 #endif
    14 extern YYSTYPE yylval;
    15 
    16 %}
    17 
    18 DIGIT   [0-9]
    19 %%
    20 
    21 \+      { printf("got plus\n"); return FUNCTION_PLUS; }
    22 \-      { printf("got minus\n"); return FUNCTION_MINUS; }
    23 {DIGIT}* { printf("got number\n"); yylval = atoi(yytext); return NUMBER; }
    24 \n      { printf("got end of line\n"); return EOL;}
    25 %%
    26 
    27 
    28 void yyerror(char* s) {
    29     printf("error %s \n",s);
    30 }
    31 
    32 int yywrap() {
    33     return -1;
    34 }
    35 [root@lex total]# 

    这里,通过 yylval,在词法分析器运行的时候,保持数据。

    再看句法分析程序:

    目前先不要求这么高,暂时看看如何在此处获得数据。

     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 EOL
    10 
    11 %%
    12 exp:
    13     NUMBER FUNCTION_PLUS NUMBER { fprintf(stderr,"---\n"); }
    14     |
    15     NUMBER FUNCTION_MINUS NUMBER { 
    16            fprintf(stderr,"left value is: %d\n",$1);
    17            fprintf(stderr,"right value is: %d\n",$3);
    18     }
    19 ;
    20 %%
    21 [root@lex total]# 

    此处,使用了 $1,$3等。

    再看主程序:

     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]# 

    运行结果:

    [root@lex total]# yacc -d parser.y
    [root@lex total]# lex lexer.l
    [root@lex total]# gcc -o myparser *.c
    [root@lex total]# ./myparser
    got number
    got minus
    got number
    left value is: 23
    right value is: 5
    [root@lex total]#

     下一篇,写一下如何构造一个结构保留语法分析的结果。

  • 相关阅读:
    How to import data from Oracle into PostgreSQL(转)
    C++——算法 回溯 八皇后问题
    Python——彩图变线稿
    算法——二叉树的遍历 前序 中序 后序 广度优先 深度优先 (转)
    C++——计数排序 (转)
    C++——位运算相关 (转)
    C++——std::vector相关 (转)
    C++——双指针 (转)
    C++——求三数之和,实操从低效做法逐步提升到高效做法,受益良多
    C++——基础容器
  • 原文地址:https://www.cnblogs.com/gaojian/p/3083959.html
Copyright © 2020-2023  润新知