LexとYaccは入門から精通へ(7)-フィルタ情報(フォールトトレランス処理)

11905 ワード

LexとYaccは入門から精通へ(7)-フィルタ情報(フォールトトレランス処理)新規ページ1
#if 0
           ,              ,              
 ,                  ,  :      C++        
  ,            ,                 C++  。  
  。  ,             ,               ,   
                        ,           。  
          C/C++       ,                C/C++
  。   Lex Yacc   (error)       :)     :)
 
                    ,         ,          
  :)
 
#endif
 
////////////////////////////////////////////////////////////////////////////////
//        :lex.l
%{
#include <string>
 
//  yylval        int   std::string  ,             
//    ,           YYSTYPE   ,    ,          
//      yacc.tab.h    ,   yacc        YYSTYPE  ,   
//          。   YYSTYPE           yacc.tab.h     
//   ,            YYSTYPE ,         YYSTYPE,    
//    YYSTYPE,   int  :)
 
#define YYSTYPE std::string
#include "yacc.tab.h"
 
#define LEX_RETURN(arg) yylval=yytext;return arg
%}
d   [0-9]
l   [a-z]
u   [A-Z]
a   {l}|{u}
%%
[;{}]                   {LEX_RETURN(yytext[0]);}
"class"                 {LEX_RETURN(CLASS);}
 
(_|{a})(_|{a}|{d})*     {LEX_RETURN(IDENTIFIER);}
 
[ \t
]                 /* */
.                       /*                */
%%
int yywrap()
{
    return 1;
}
////////////////////////////////////////////////////////////////////////////////
 
 
////////////////////////////////////////////////////////////////////////////////
//        :yacc.y
%{
#include <iostream>
#define YYSTYPE std::string
extern int yylex();
void yyerror(const char*msg);
%}
%token CLASS IDENTIFIER
%%
program:/*   */
       | program class //  C++  
       | program error ';' //                 ,         
                           //            error,   yacc       
                           //     CLASS IDENTIFIER              
                           //    
       ;
class://          class        program,             
       CLASS IDENTIFIER '{' program '}' ';' {std::cout<<"    :"<<$2<<std::endl;}
     ;
%%
void yyerror(const char*msg)
{
    //     ,              ,                
    //          ,                       
    std::cerr<< "    " << std::endl;
}
int main()
{
    yyparse();
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
 
////////////////////////////////////////////////////////////////////////////////
// Makefile  
CC=g++
CFLAGS=
LEX=flex
YACC=bison
YACCFLAGS=-d
TARGET=lexyacc
 
$(TARGET):lex.yy.c yacc.tab.h yacc.tab.c
    $(CC) $(CFLAGS) lex.yy.c yacc.tab.c -o $(TARGET)
lex.yy.c:lex.l
    $(LEX) lex.l
yacc.tab.c yacc.tab.h:yacc.y
    $(YACC) $(YACCFLAGS) yacc.y
 
clean:
    rm -f lex.yy.c yacc.tab.h yacc.tab.c
////////////////////////////////////////////////////////////////////////////////
 
//            ,        ,                 
//            ,                 。        
//                。                  ,   
//               ,             :
// 1:yacc     error     
// 2:     yylval int   std::string  
//            C++ ,              ,    ,   
//    ;)
//
//   ,                      :D,           
// 。    Lex Yacc      ,                     
//  ,                     :)    :)
 
//        
////////////////////////////////////////////////////////////////////////////////
//     :sample.cpp
class Point
{
    int x;
    int y;
    int GetX();
    int GetY();
};
 
class Rect
{
    int x;
    int y;
    int w;
    int h;
    int GetX();
    int GetY();
    int GetW();
    int GetH();
};
 
class Wrapper
{
    class Inner1{};
    class Inner2{
        class InnerInner1{float f;};
        class InnerInner2{};
        std::string name;
    };
    bool sex;
};
////////////////////////////////////////////////////////////////////////////////
 
////////////////////////////////////////////////////////////////////////////////
//        
D:\home\blog\lexyacc>make
flex lex.l
bison -d yacc.y
g++ lex.yy.c yacc.tab.c -o lexyacc
 
D:\home\blog\lexyacc>lexyacc.exe < sample.cpp
    
    :Point
    
    :Rect
    :Inner1
    
    :InnerInner1
    :InnerInner2
    
    :Inner2
    
    :Wrapper
 
D:\home\blog\lexyacc>