  Lex & Yacc(Ұ  ߽)

    byosmosis@yahoo.com
  1997 11 1

   ...    Ʈ  ִ ۼ߾
  Դϴ. ^^;  ؽƮ   ֵ ٲپ Խմϴ. lex &
  yacc .  :) Lex Yacc Է± ˻ м ϰ
  ϱ Ͽ ߵǾ.  Է¿     ϴ 
  α׷     Ȯϰ ׸ ణ 
    Ǵ  lex yacc Ư¡̴.     Lex Yacc
  ̴ δ ڿ ڸ  ϴ , Ϸ
     ˻,  м  ̳, Ÿ
  ̽ SQL  üũϴ ,  lex ̿  м
    쿡 ̿ȴ.  ⼭ lex yacc  Ұ
  lex yacc ̿ϴ  ׸ ణ lex yacc   ؼ
  Ұϰ Ѵ.
  ______________________________________________________________________

  

  1. Lex & Yacc
     1.1 Lex (Lex ̿  α׷)
     1.2 Lex Yacc (Lex scanner, Yacc parser)
     1.3 Yacc 
     1.4 Lex Yacc ̿
     1.5 Makefile ̿

  2. 

  ______________________________________________________________________

  1.  Lex & Yacc

  lex yacc (Bell Laboratories) 70뿡 ߵǾ, Ŀ
  ̰͵ н ǥ ƿƼ  Ǿ System V ʱ BSD
    AT&T  ̿ǰ  ο BSDδ flex
  Berkely yacc  ̿ǰ ִ.   FSF(Free Software Foundation)
  GNU Ʈ bison̶ Ҹ  yacc    
   BSD GNU Ʈ flex(Fast Lexical Analyzer
  Generator)ܿ  üϿ   ٸ ̸ lex
  yacc  ǰ ִ.

   MS-DOS OS/2  OS󿡼 ̿  ִ lex yacc 
   MKS(Mortice Kern Systems Inc.) ִ.

  1.1.  Lex (Lex ̿  α׷)

  )  Lex Ʒ  %% %%̿ lex ǰ  Ŀ
  C ȴ.

       %%
       .|\n    ECHO;
       %%

       main()
       {
               yylex();
       }

   ǥԷ ǥ    lex α׷
   ǥ . \n ǥõǴ ڰ   ״ ش.
  ( lex   default̴.)

   ٸ    

        [\t ]+          ;       # whitespace Ѵ

   %% %%̿ ԽŰ ̶簡 ϳ ̻  ִ 
  C  ƹ ó ִ ';' Ͽ  ƹ
  ó  ʴ´.(ȭ鿡  ޽   ʴ´.)

   ҽ simple.l̶ ϸ( ǥô  Է)

       [ post ] % lex simple.l
                                  # lex C, lex.yy.c 
       [ post ] % cc lex.yy.c -o simple -ll
                                  # lex̺귯  
       [ post ] % ./simple < simple.l
                                  # simple.l ǥԷ ϴ α׷ 
       %%
       .|\n ECHO;
       %%

       main()
       {
               yylex();
       }

    Ǿ UNIX cat   α׷ ϼȴ.(ڰ 
  cat     α׷ )

   lex    definitions, rules, user code section
  ̷.

       definitions
         # rules pattern ϰ ϱ   ʱ 
         # Cڵ Խ %{, }% ȣ ǥϰ ̿   
       %%
       rules
         # pattern action ̷
         # Cڵ {, } μ ǥ
       %%
       user code
         # yylex()Լ ڰ ϴ C ƾ ̷

  )

   %% %%̿ lex ϱ  C ϱ⸦ ҽÿ %{
  %} C ̶ ǥø ϰ  ̿   ִ.

       %{
               /*
                * My favorite...
                */
       %}
       %%

       [\t ]+  ;
       rain |
       rose            { printf("%s!! That is my favorite.\n", yytext); }
       love |
       story           { printf("%s!! I like a love story. ^_~\n", yytext); }
       "potato chip" |
       potato |
       chip  { printf("%s...!! now and then, I have a potato chip.\n", yytext); }

       [A-Za-z]+ { printf("%s..., what is that?\n", yytext); }

       .|\n    { ECHO; }

       %%

       main()
       {
               yylex();
       }

  yytext lex Ǵ Է ؽƮ  global character
  pointer̴.   ҽ simple.l   Ͽ 
  

       [ post ] % ./favor
       potato chip
       potato chip...!! now and then, I have a potato chip.

       love7
       love!! I like a love story. ^_~
       7
       distress
       distress...,  what is that?
         ȴ.

       lovestory
       lovestory...,  what is that?

       love story
       love!! I like a love story. ^_~
       story!! I like a love story. ^_~

   Ÿ  °  óϱ⸦ ϴ Ͽ ؼ
  ó ̷.  love7 쿡 love  ó ְ 7
  ĺ ƴϹǷ ٿ ڰ ȴ.    ٷ  'love
  story' love νϰ whitespace ĭ νϰ  story
  ν ̴.   love  ó ĭ  ƹ ó
  story  ó    ̴.   μ loveyou
  Է ߴٸ love  you    ƴ϶ ϳ 
   distress       ִ.

  )       ٸ ڿ  C
  enum Ͽ ɺ ̺  ̿ϴ  ش.

  [ post ] % cat number.l
  %{
  enum {
          NONE = 0,
          ONE,
          TWO,
          THREE,
          FOUR,
          FIVE,
          SIX,
   SEVEN
  };

  int number;
  void action();
  %}

  %%
  oneone  { number = SEVEN; action(); }
  one |
  ONE  { number = ONE; action(); }
  two |
  TWO  { number = TWO; action(); }
  three |
  THREE  { number = THREE; action(); }
  four |
  FOUR  { number = FOUR; action(); }
  five |
  FIVE  { number = FIVE; action(); }
  six |
  SIX  { number = SIX;  action(); }
  [a-zA-Z]+ { number = NONE; action(); }
  %%

  void action()
  {
          if (number != NONE)
                  printf("%s is %d\n", yytext, number);
          else
                  printf("%s?? I don't learn it.\n", yytext);
  }

  main()
  {
          yylex();
  }

  [ post ] % ./number
  tow
  tow?? I don't learn it.

  five
  five is 5

  four7
  four is 4
  7
  SIX
  SIX is 6

  ten
  ten?? I don't learn it.

  oneone
  oneone is 7

  twotwo
  twotwo?? I don't learn it.

  two two
  two is 2
   two is 2

    'two two' two  ó ְ ' ' ĭ 
  ٿ ܼ ְ ٷ Ѿ ʰ  two óǾ
  Ÿ ̴.   ° two տ ĭ ϳ  ִ.
  ׸ oneone̶    one  ƴ oneone
      ڿ 켱  ̴.( ǥ
  )

  )  lex   ͺ ణ  ڿ ڿ
   νϴ μ ݸ Ű   α׷ 
   ִ.    ܼ , ,  Ǵ μ
    Ͽ Ÿ ϴ ̴.

       %{
       /* need this for the call to atof() below */
       #include <math.h>
       %}

       DIGIT    [0-9]  /* ũθ Ѵ */
       ID       [a-z][a-z0-9]*

       %%
       {DIGIT}+  { printf( "An integer: %s (%d)\n", yytext, atoi( yytext ) ); }
       {DIGIT}+"."{DIGIT}* { printf( "A float: %s (%g)\n", yytext, atof( yytext ) );
       }
       if|then|begin|end|procedure|function { printf( "A keyword: %s\n", yytext ); }
       {ID}   { printf( "An identifier: %s\n", yytext ); }
       "+"|"-"|"*"|"/"  { printf( "An operator: %s\n", yytext ); }
       "{"[^}\n]*"}"  ; /* { }   ּ Ѵ. */
       [ \t\n]+  ; /* whitespace Ѵ. */
       .   printf( "Unrecognized character: %s\n", yytext );
       %%

       main( argc, argv )
       int argc;
       char **argv;
       {
           ++argv, --argc;  /* skip over program name */
           if ( argc > 0 )
                   yyin = fopen( argv[0], "r" );
           else
                   yyin = stdin;

           yylex();
       }

    yyin   Է Ŀǵ λ ùڰ
  Ű   ó  ȭ鿡 ǥԷ ޾ ó
    ó   ְ Ѵ.

  1.2.  Lex Yacc (Lex scanner, Yacc parser)

  Lex scanner Yacc parser  ϴ 찡 κε, Yacc
  Lex  ȴ.  Lex Է¹ڿ   ˻ ϰ
   м Yacc ϴ ̴.  Yacc Է¿  ū(token)
  ʿϸ, Lex ϴ yylex()Լ ȣϿ, Էµ  ū
  迭 ־  ´ üũϸ鼭  ǿ ´  ϰ
  ȴ.  ٸ ǥϸ, Lex Yacc  ÿ  ÿ yacc
   main()Լ yyparse()Լ yacc  
  м⸦ θ, yyparse()Լ yylex() lex  ִ
  ؼ(lexer) ̿ؼ Է¿ ó ū ̾ƿ ȴ.
    lex '[\t ]+' ǥõǾ ̳ ǰ 
  whitespaceڴ κ α׷  óϱ⸦ ġ ʴ´.
     ǹ  ڳ ó ʿ䰡  ڿ ؼ
    parser Ѱ ʿ䰡 . ׸   ó
  ڰ    (ū) yacc parser ѱ  ó 
  ̴.  ̷ 찡 lex yacc   Ǵ    
   ̴.

   MS-DOS OS/2  OS󿡼 ̿  ִ lex yacc ߴ
  MKS(Mortice Kern Systems Inc.) WWW Ͽ Netscape
  Fasttrack̳ Microsoft IIS  ˻   ̿  ְԵ
  Ͽ.

  1.3.  Yacc 

  Yacc Yet Another Compiler Compiler ڷ, Ϸ  
  α׷ compiler-generator Ǵ compiler-compiler θµ,
  Yacc BNF   rules ׸κ parser 
  α׷̴.(Yacc Է BNF ϰ   ̴.)  Yacc
  ̿ α׷ portable C Ϸ, APL, Pascal, Ratfor, tbl, eqn
   ִ.

   Yacc ̸, Yacc Lex    ִµ
  δ Lex Yacc    ̴.

       definitions
          # Cڵ Խ %{, }% ȣ ǥϰ ̿   
       %%
       rules
          #  rule "LHS: RHS;"   ̷
       %%
       user code
          # lex ս yylex() ̿Ѵ.

        LHS left-hand symbol ڷ ':' ʿ  statement,
          expression  ʿ  ȣ ϸ,  RHS right-hand
          symbol ڷ ':' ʿ  ȣ Ѵ.
           rule  ';' ǥѴ.

  ) yacc ظ       
     ⸦ ٰ   װ   
  ̸ Ʒ .

  [ post ] % cat y_calc.y
  %token NAME NUMBER
  %%
  statement:    NAME '=' expression
              | expression  { printf("= %d\n", $1); }
              ;
  expression:   expression '+' NUMBER { $$ = $1 + $3; }
              |   expression '-' NUMBER { $$ = $1 - $3; }
              |   NUMBER  { $$ = $1; }
              ;
  [ post ] % cat y_calc.l
  %{
  #include  "y.tab.h"
  extern int  yylval;
  %}
  %%
  [0-9]+ { yylval = atoi(yytext); return NUMBER;  }
  [\t ]+ ;
  \n return 0;    /*  Էó  */
  . return  yytext[0];
  %%

  yacc lex ȣϸ(=yylex() ȣϸ) NAME, NUMBER, ׸ +, -,
  = · ū Ѱ ޴´.(Խ ǥ ؼ ' 'ȿ 
  ڴ    ü )  y_calc.y , $1, $2, $3 
  Է¹ ū ġ شϴ   ְ,   yacc
  yylval type int,  ó Ǿ %d 
  Ѵ.(y_calc.l ϰ ִ yylval̶  union
  Ǿ ִ.  ̰ lex ܺκ  ̿Ͽ
  yyparse()Լ ȣϴ yacc óϵ  ϰ Ǵ )
  ׸ $2 쿡 شϴ  ڿ شϴ ڰ 
   expression RHS { } ȿ +,  - ̿ϰ ִ.  ׸
  $$ LHS , expression  ȴ.

  yacc  ϱ ؼ example.y yacc ۼǸ yacc
  ̿Ͽ, yyparse() м Լ  y.tab.c C
  ȭ  ؼ 'yacc example.y' ϰ CϷ ̿ؼ,
  y.tab.o Ʈ ȭ  Ŀ, ڵ⳪ ٸ α׷
  ũϿ ϴ  .   α׷(y_calc.y y_calc.l)
  Ͽ   Ʒ .

       [ post ] % yacc -d y_calc.y /* y.tab.h y.tab.c  */
       [ post ] % lex y_calc.l
       [ post ] % cc -o y_calc y.tab.c lex.yy.c -ly -ll
       [ post ] % ./y_calc
       1+101
       = 102
       [ post ] % ./y_calc
       1000-300+200+100
       = 1000

  ⼭ y.tab.h lexer includeϱ , yacc ֱ
   -d ġ ̿Ͽ. lex ̿Ͽ, lex.yy.c , yacc
  ̿Ͽ, y.tab.c  liby.a libl.a ũϿ ϴ
  ȭ  ȴ.

   Yacc ȣ  -    غ.

  expression : expression '+' expression
      |        expression '-' expression
      |        expression '*' expression
      |        expression '/' expression
      |        '-' expression
      |        '(' expression ')'
      |        NUMBER

   yacc  , 2+3*4 ĽϷ ϸ, ׸ ,
  (2+3)*4 ĽƮ   ְ, 2+(3*4) ó  ְ
  Ǿ,   ȴ.  2-3-4-5 쿡, 2-(3-(4-5)),
  (2-3)-(4-5)   ȴ  ָ   ٲ
   ִµ, 켱 չĢ  ϴ  Ѱ
     ʰ  ̰, ٸ Ѱ ̷ 
  ذϱ Ͽ yacc Ǿ ִ ϴ  ̿Ͽ(%prec,
  %left, %right, ...) 켱 չĢ ϴ ̴.  ̸
  ذϴ   ٲٴ  ⺻ ̵ 켱
    ڿ ؼ LHS  , ̸ reduceǵ
  ϴ ̸, չĢ ؼ   ذ  ִ.
    ٲپ shift/reduce conflict ذ  Ʒ .

       expression: expression '+' mulexp
         |   expression '-' mulexp
         |   mulexp
         ;
       mulexp : mulexp '*' primary
         |   mulexp '/' primary
         |   primary
         ;
       primary:  '(' expression ')'
         |   '-' primary
         |   NUMBER
         ;

   ذϴ Ǵٸ  yacc ϴ ɾ ̿ϴ
    ɾ ̿ؼ, 켱  չĢ   ְ
  ȴ.       .

       %left  '+' '-'
       %left  '*' '/'
       %right '='
       %nonassoc  UMINUS /* unary operator Ƿ չĢ  ȵȴ.  */

    ϰ Ǹ, + - * / =  켱 + -   , *
  / װͺ , Կ =  , ȣ -  
  켱 ٴ  ְ ִ.   + -, *, / 
  չĢ , Կ =  չĢ .

  %token NAME NUMBER
  %left '-' '+'
  %left '*' '/'
  %nonassoc UMINUS
  expression:     expression '+' expression
           |      expression '-' expression
           |      expression '*' expression
           |      expression '/' expression
           |      '-' expression %prec UMINUS
           |      '(' expression ')'
           |      NUMBER
           ;

   ߰ ̴ %prec UMINUS '-' expression  ڿ
  Ľϰ Ǹ - ؼ UMINUS  켱 ϶
  ǹ̴.  , ȣ  ̴ shift/reduce conflict
  涧, 켱 չĢ ν,  ذ  ְ
  ȴ.

   Ǵٸ Yacc ȣ, LALR(1) ƴ     
  캸.

       phrase: cart_animal AND CART
               | work_animal  AND PLOW
       cart_animal: HORSE | GOAT
       work_animal: HORSE | OX

    , HORSE AND CART  Է  쿡, HORSE
  cart_animal reduceؾ ϴ, work_animal reduceؾ ϴ
  ˷, HORSE , AND , CART     ְ
  ȴ.  Yacc ó    , yacc  м ϴµ
  ϴ  LALR(1)ε LALR LookAhead Left Recursive, , 
   ܾ   ´    ִٴ ̱ ̴.
  , HORSE  2 ܾ  о ϴ ε,  
  LALR(2)̸, yacc   lookahead   ִ 
  LALR(1) شϹǷ,   ó  .   
    LALR(1) ٲپ ־ Ѵ.

       phrase -> cart_animal  CART
                | work_animal  PLOW
       cart_animal  -> HORSE | GOAT
       work_animal -> HORSE | OX

    HORSE , ٷ   ܾ CART 
  cart_animal reduce, work_animal reduceؾ ˰ ȴ.

  )    ó  Ź ⸦ Ϸ Ѵ.

  a = 2.3 + 3.5
  b = 3.5 + 5.2
  c = a + b - 1
  c
  = 13.5

     Ϸ ⺻ ҷ   ִ
  ɺ̺ ϰ,  ɺ̺  ̸  ؾ Ѵ.
   ̸  ĺ ٰ  ׷  
  ̴.

       [ post ] % cat variable.y
       %{
       double vbltable[26];  /* double  迭 */
       %}
       %union  {
                       double dval;
                       int vblno;
               }
       %token    <vblno> NAME
       %token    <dval> NUMBER
       %left '-' '+'
       %left '*' '/'
       %nonassoc UMINUS
       %type <dval> expression
       %%
       statement_list: statement '\n'
                 |         statement_list statement '\n'
                 ;
       statement:        NAME '=' expression  { vbltable[$1] = $3; }
                 |   expression                 { printf("= %g\n",$1); }
                 ;
       expression: expression '+' expression  { $$ = $1 + $3;  }
                 | expression '-' expression  { $$ = $1 - $3;  }
                 | expression '*' expression  { $$ = $1 * $3;  }
                 | expression '/' expression
                           {  if($3 == 0.0)
                                    yyerror("divide by zero");
                              else   $$ = $1 /$3;
                           }
                  |  '-'expression  %prec UMINUS   { $$ = -$2; }
                  |  '('expression')'     { $$ = $2; }
                  |       NUMBER
                  |       NAME       { $$ = vbltable[$1]; }
                  ;
       %%
       main()
       {
           yyparse();
       }

  ̸  ĺ  26 Ҹ  迭
  vbltable[26] ؼ   ϵ Ѵ.   %union
  lexer ޴ token NAME NUMBER NAME vbltable[]  ε
  Īϰ Ͽ, 0 25   ϴ ݸ鿡, NUMBER Ǽ
    Ѵ.  ,  token̶ ϴ,  
  ٸ Ǵµ,   ޶,      token
  νĵǱ ,  Ҹ ϵ   %union
  ϰ ȴ.  ׸ %union , y.tab.cȿ C union
  ȯǾ óȴ.  ``%type <dval> expression''  , token
  ƴ϶ token   LHS 쿡 ˸ Ÿ 
  ϴٴ  ش.  ``NAME '=' expression  { vbltable[$1] = $3;
  }''    reduce   actionθ ϰ
  Ǵµ, ǹ̴ $1  NAME (0 25  yylex()κ
  ޾Ҵ) vbltable  ҿ $3  expression  ִ ̴.
    x = 2.0 + 3.2̾ x  $1 23 Ǹ vbltable[23] =
  5.2 ǹ̸ .   ``'-' expression %prec UMINUS  {  $$ = -$2;
  }''  -2  ܾ   - 2-3 - ƴ϶
  %prec  ȣ - 켱  ξ  ̷
  ǹѴ.  ``NAME    { $$ = vbltable[$1];  }''  y ̸
  ־ $1  0 25  ߿ 24° شǹǷ
  vbltable[24]  ÿ ϰ ȴ.

       [ post ] % cat variable.l
       %{
       #include "y.tab.h"
       #include <math.h>

       extern double vbltable[26];
       %}
       %%
       ([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?)  {
                         yylval.dval = atof(yytext); return NUMBER;
                       }
       [\t]   ;        /* ignore white space */
       [a-z]    {      yylval.vblno = yytext[0] - 'a'; return NAME; }
       "$"      { return 0; }    /*  end of input  */
       \n       |
       .                return yytext[0];
       %%

   lexȭ , yylval.dval ǥ  ִ , ̰
  yylval unionŸ  ǾǷ, NUMBER̸, 
  , yylval.dval Ͽ,   Ÿ.  
    ĺ ϱ , ܼ 0 25 
  vbltable εϰ Ǵµ, lex yylval.vblno = yytext[0] -
  'a' yylval 0 25  ְ ȴ.  
  α׷(variable.l  variable.y) Ͽ   Ʒ
  .

       [ post ] % yacc -d variable.y
       [ post ] % lex variable.l
       [ post ] % cc -o variable y.tab.c lex.yy.c -ll
       [ post ] % ./variable
       7.5+3.5
       = 10
       200/20+20/2
       = 20
       x=20/2
       y=x+1
       y
       = 11

  1.4.  Lex Yacc ̿

    Lex Yacc ÿ Ͽ  ̴.

  [ post ] % cat example.h
  #define NOUN 257
  #define PRONOUN 258
  #define  VERB  259
  #define  ADVERB  260
  #define  ADJECTIVE  261
  #define  PREPOSITION   262
  #define  CONJUNCTION 263
  [ post ] % cat example.l
  %{
  /*
   * build a lexical analyzer to be used by a high-level parser.
   */
  #include "example.h" /* token codes from the parser */
  #define LOOKUP 0 /* default - not a defined word type.  */
  int state;

  %}
  %%

  \n { state = LOOKUP; }
  \.\n { state = LOOKUP; return 0; }  /*   ó  ǹ */
  ^verb { state = VERB;  }
  ^adj { state = ADJECTIVE; }
  ^adv { state = ADVERB; }
  ^noun { state = NOUN; }
  ^prep { state = PREPOSITION; }
  ^pron { state = PRONOUN; }
  ^conj { state = CONJUNCTION; }
  [a-zA-Z]+ {
              if (state != LOOKUP) {
                    add_word(state, yytext);
              } else {
                    switch(lookup_word(yytext))
                    {
                        case VERB  : return(VERB);
                        case ADJECTIVE : return(ADJECTIVE);
                        case ADVERB  : return(ADVERB);
                        case NOUN  : return(NOUN);
                        case PREPOSITION : return(PREPOSITION);
                        case PRONOUN : return(PRONOUN);
                        case CONJUNCTION : return(CONJUNCTION);
                        default   : printf("%s: don't reconize\n", yytext);
                                             /*  don't return just ignore it  */
                    }
              }
            }
  .   ;

  %%
  /*  ܾ Ÿ Ͽ ܾ    ü  */
  struct word {
          char *word_name;
          int  word_type;
          struct word *next;
  };
  struct word *word_list;
  extern void *malloc();

  int add_word(type, word)
  int type; char *word;
  {
          struct word *wp;
          if (lookup_word(word) != LOOKUP) {
                  printf("!!! warning: word %s already defined \n",word);
                  return 0;
          }

          /*  word not there, allocate a new entry and link it on the list */
          wp = (struct word *) malloc(sizeof(struct word));
          wp->next = word_list;
          /* have to copy the word itself as well */

          wp->word_name = (char *)malloc(strlen(word)+1);
          strcpy(wp->word_name, word);
          wp->word_type = type;
          word_list = wp;
          return 1;    /* it worked */
  }

  int lookup_word(word)
  char *word;
  {
          struct word *wp = word_list;
          /*  search down the list looking for the word  */
          for (; wp; wp = wp->next) {
                  if (strcmp(wp->word_name, word) == 0)
                          return wp->word_type;
          }
          return LOOKUP; /*  not found  */
  }

  verb, noun  ؼ state ̿Ͽ,    
  ܾ ɺ̺ ϰ Ǵ  add_word()Լ̰  ϵ
  ܾ 캸 Լ  lookup_word()̴.

   yaccȭ example.yȭ ̴.

  [ post ] % cat example.y
  %{
   /*
    A lexer for basic grammar to use for recognizing english sentences.
    */
  #include <stdio.h>
  %}
  %token  NOUN PRONOUN VERB ADVERB ADJECTIVE PREPOSITION CONJUNCTION
  %%
  sentence: subject VERB object { printf("Sentence is valid.\n"); }
    ;
  subject:  NOUN
    | PRONOUN
    ;
  object:  NOUN
    ;
  %%

  extern FILE *yyin;
  main()
  {
    while(!feof(yyin)) {
       yyparse();
    }
  }

  yyerror(s)
  char *s;
  {
    fprintf(stderr,"%s\n",s);
  }

   yaccȭϿ "%token NOUN PRONOUN VERB ADVERB ADJECTIVE
  PREPOSITION CONJUNCTION" Է ⺻ ū óѴٴ 
  ǹϰ ⼭ lexerԼ Ѱܹ޴  ȴ.  , yyparse()
  Ź yylex() θ,   NOUN̳ PRONOUN  token 
  Ǵ ̴.  , yyparse ׷ ū    ´
  мϿ,   ־, action C  ϰ ȴ.
  yacc Է yyin̶ ȭϿ  ǰ,  yyout̶
  ȭϷ  ȴ.  ⺻δ yyin yyout stdin stdout,  ǥ
  ,  ǾǷ, Ű ȭ  
  ̷ ȴ.  ̸ ٲپִ  տ Ͽ.
  yyparse() yacc ִ м(parser)̰, yyerror()
  м ߿    θ Լ̴.   տ 
  lexȭ(example.l) yaccȭ(example.y)  Ͽ 
  ̴.

  [ post ] % lex example.l
  [ post ] % yacc example.y
  [ post ] % cc -o example lex.yy.c y.tab.c -ll
  [ post ] % ./example
  noun pig fish I
  verb run am are
  verb outrun
  pig outrun fish
  Sentence is valid.
  noun you
  you are pig
  Sentence is valid.
  pig are
  syntax error
  syntax error
  pig outrun fish.
  Sentence is valid.
  verb am
  !!! warning: word am already defined
  I am fish
  Sentence is valid.
  i am fish
  i: don't reconize
  syntax error

  1.5.  Makefile ̿

    ȭϰ, α׷   ϱ ؼ  
  makefile Ͽ ϰ    ִ.

       [ post ] % cat makefile
       CC = cc
       LIBS = -ll
       LEX = lex
       YACC = yacc
       CFLAGS = -DYYDEBUG=1
       all: speech
       speech: y.tab.c lex.yy.c
                       $(CC) -o speech y.tab.c lex.yy.c $(LIBS)
       y.tab.c: example.y
                       $(YACC) -d example.y
       lex.yy.c : exaple.l
                       $(LEX) example-07.l
       [ post ] % make
       cc -o speech y.tab.c lex.yy.c -ll

  2.  

  o  lex & yacc - O'Reilly & Associates. Inc.

