  Lex and YACC primer/HOWTO
  PowerDNS BV (bert hubert <bert@powerdns.com>)
  v0.8 $Date: 2002/07/22 14:02:09 $
  吼  (daiki onishi <onishi@mbc.nifty.com>)
  v0.8j 2003/02/08

  {hLg Lex  YACC ̊{IȎgɂċLq܂
  ______________________________________________________________________

  ڎ

  1. Cg_NV
     1.1 {hLgɊ܂܂Ȃ
     1.2 _E[h
     1.3 CZXɂ

  2. Lex  YACC łł邱
     2.1 ꂼ̃vÔĂ邱

  3. Lex
     3.1 K\ł̃}b`
     3.2 C ̂悤ȃV^bNXxȗ
     3.3 炢

  4. YACC
     4.1 Pȉxߊ
        4.1.1 YACC t@C̑S
        4.1.2 xߊ̃RpCƋN
     4.2 悤ɊgAxߊ
     4.3 ݒt@C̍\

  5. C++ ł̍\͊̍쐬
  6. Lex  YACC ̓
     6.1 g[N̒l
     6.2 ċA - 'P(right=Ej͈'
     6.3 荂x yylval - %union

  7. fobO
     7.1 Xe[g}V
     7.2 RtNg: 'shift/reduce', 'reduce/reduce'

  8. ֘A
  9. ӎ

  ______________________________________________________________________

  1.  Cg_NV

  悤AMȂǎ҂݂̂Ȃ

  Unix ŁAxvO~Ooς܂ĂȂALex &
  YACCA GNU/Linux [ŮԂ Flex & Bison ƂĒmĂ
  A_IȃvOm̂ƂƎv܂BFlex Ƃ́AVern Paxon
  ɂ Lex łABison Ƃ GNU  YACC łBȉAf̂Ȃ
  肱 Lex & YACC ƌĂԂƂɂ܂ - Flex & Bison ́ALex & YACC
  Əʌ݊ɂ̂ŁA{hLg̃Tv̂܂ܓ삵܂B

  ̃vÓAɗpl̍̂łBAC RpC
   man y[Wł悤ɁAdl͂ƂgɂĂ
  疞ȋLq܂BYACC  Lex Ƒgݍ킹ĎgƁAʂ
  ̂łABison  man y[Wɂ Lex ŐꂽR[h
  Bison ̃vO삳@ɂĂ̋Lq܂B

  1.1.  {hLgɊ܂܂Ȃ

  Lex & YACC ɂẮAǏ܂B[m肽̂ł
  ΁AǂނƂ߂܂B{hLgɏĂA
  Ƃ̏񂪓͂łB '֘A' ̏͂
  Bł́Aǎ҂ȒPȃvOg߂xɁALex & YACC ̊{
  IȎg邱ƂɓeƂǂ߂܂B

  Flex  BISON ɕtĂhLgǂ̂łA`[gA
  ܂B HOWTO ̑Ȃ⊮镪ɂ͗LpłB
  ɊւĂÅ֘Ȁ͂B

  M҂ YACC/Lex ̃GLXp[gł͂܂B̃hLgn
  ߂łA傤Ǔ̌o܂łBM҂̊肢́A
  ԂFɂƂāAłyȂ̂ɂĂƂƂɐs
  ܂B

  ɗᎦAYACC  Lex ̃R[fBOX^CɍłK؂ł
  Ƃ͌܂BR[h̓Vvɂ悤w߂܂Aǂ
  邩܂BCÂ̓_ΐAB

  1.2.  _E[h

  ᎦĂR[h́Aׂ machine readable Ȍ`Ń_E[h
  ܂Bڍׂ z[y[W <http://ds9a.nl/lex-yacc> B

  1.3.  CZXɂ

  Copyright (c) 2001 by bert hubert. ̒앨̔zzɊւĂ Open
  Publication License, vX.Y ܂͂ȍ~Œ߂ĂKƏɏ
  ܂iŐVł http://www.opencontent.org/openpub/ œ\
  jB

  2.  Lex  YACC łł邱

  ̃vO𐳂pƁAȒPɕGȌ̍\͂ł
  悤ɂȂ܂Bɐݒt@Cǂݍ݂A܂͑l
  Ăp̃RpCȂǂɁAɏƂȂ܂B

  ̃hLgł́A킸Ȏ菕ɂȂȂ܂񂪁A
  łAƂō\͊ (Parser) Ă݂悤Ƃ͎vȂȂ
  ͂ł - Lex & YACCƂ͂̂悤ȍƂĂc[łB

  2.1.  ꂼ̃vÔĂ邱

  ̃vÓAgݍ킹ĎgƂ΂炵̂łAꂼ
  ͈ړȈɍĂ܂B͂ł͂ꂼꂪĂ邱Ƃ
  ܂B

  3.  Lex

  Lex vO '͊ (Lexer)' ƌĂ΂̂𐶐܂B
  ͓͂ɕXg[Ƃ֐ŁAL[Ƀ}b`镶Q
  ɁA錈܂邱Ƃł܂Bȉ͂̊ȒPȗ
  B

       %{
       #include <stdio.h>
       %}

       %%
       stop    printf("Stop command received\n");
       start   printf("Start command received\n");
       %%

  %{  %} ̑gŊŏ̃ZNV́Ao̓vOł͒ڃC
  N[h܂B́Astdio.h Œ`Ă printf AŕKv
  ƂȂ邽߂łB

  ZNV '%%' ŋ؂Aڂ̃ZNV̑s 'stop' L[
  Ŏn܂邱ƂɂȂ܂B͂ 'stop' L[́Acs (
  printf() Ăяo) s܂B

  "stop" ɉāAł "start" ƂقƂǓ̂
  `܂B

  L̃R[hZNV '%%' ŕ܂B

  Example 1 RpCɂ͈ȉ̂悤ɂ܂B

       lex example1.l
       cc lex.yy.c -o example1 -ll

        - lex ̑ flex gpẮARpCXNvg
       '- ll'  '-lfl' ɒuKv邩܂BRedHat 6.x
       SuSE ł 'flex'  'lex' ƂċNĂ邩܂񂪁A̕
       XKvł!

  ȏɂA'example1' Ƃt@CꂽƎv܂Bs
  ƁAL[{[h̓͑҂ɂȂ܂B`ς݂̃L[ ( A'stop'
   'start') ȊÔ̂͂ƁAꂪ̂܂܏o͂܂B'stop'
  ͂ƁA'Stop command received' o͂܂B

  EOF (^D) ŃvOI邱Ƃł܂B

  main() ֐`ĂȂ̂ɁAǂăvÔs
  vcɎvꂽ܂B́A-ll R}hŃRpCɃ
  N libl (liblex) Amain() ֐̒`܂łłB

  3.1.  K\ł̃}b`

  Ĺ̗Aꎩgł͂܂ĝł͂܂łB̗
  قǗpl̂̂ł͂Ȃ̂łAXd󂷂邱ƂɂȂA
  Lex ł̐K\̎gᎦĂ܂B

  Example 2:

       %{
       #include <stdio.h>
       %}

       %%
       [0123456789]+           printf("NUMBER\n");
       [a-zA-Z][a-zA-Z0-9]*    printf("WORD\n");
       %%

   Lex t@Cł WORD  NUMBER ƂAނ̃}b`ig[N
  jLqĂ܂BK\ƕƂтĂ܂l邩
  ܂񂪁Aƕ׋΂ɗł悤ɂȂ̂łBNUMBER
  ɑ΂}b`Ă݂܂傤B

  [0123456789]+

  ́A0123456789 ̂ǂꂩꕶ܂ޕA܂͕񂪑݂
  ӖłBȉ̂悤Ȋȗ\Lł܂B

  [0-9]+

  WORD }b`͂GɂȂ܂B

  [a-zA-Z][a-zA-Z0-9]*

  ÓA'a'  'z' ܂ 'A'  'Z' ̊Ԃ̕A܂A
  t@xbĝǂꂩƂӖłBAt@xbǧɂ́AAt@xb
  g̓ArA[ȏ㑱܂BAX^XNgĂ
  ͉̂ł傤H '+' Ƃ͈̂ȏ̃}b`\܂AWORD ́A
  OŊɃ}b`ꕶ݂̂Ƃ\܂B̏ꍇ
  ́A㔼ł̃}b`[ɂȂĂ܂̂ŁA'*' ƂKv
  łB

  ̂悤ɂāÃvO~Oꂪv悤ȁAŏ̕
  At@xbg n܂ȂĂ *Ȃ炸*Ǎ̓ArA܂
  ǂƂ悤ȁAϐ̋KɎ̂邱Ƃł܂B
  ܂A'temperature1' ͗ǂłA'1temperature' ͂߂ƂƂɂ
  ܂B

  Example 1 ł悤ɁAExample 2 RpCĂ݂ĂB
  ȉ̗̂悤ɃeLXg͂Ă݂ĂB

       $ ./example2
       foo
       WORD

       bar
       WORD

       123
       NUMBER

       bar123
       WORD

       123bar
       NUMBER
       WORD

  o͂̃zCgXy[Xǂ痈̂AsvcɎvꂽ܂
  BR͊ȒPłB́AƂƓ͂Ɋ܂܂Ă̂łA
  }b`Ȃ߂̂܂܏o͂ƂȂČꂽƂ̘błB

  Flex  man y[Wɂ́AgĂ鐳K\ɂďڂڂĂ
  B܂Aperl ̐K\ man y[W (perlre) ֗Ɗ
  X񂢂܂ - Ƃ Flex ̐K\̎́Aperl قǊS
  ͂܂񂪁B

  "[0-9]*" ̂悤ɁA[̃}b`͍sȂ悤ɒӂĂB
  ͊킪Ă܂A󕶎Ƃ̃}b`JԂ悤ȂƂɂ
  ܂B

  3.2.  C ̂悤ȃV^bNXxȗ

  ȉ̂悤Ȑݒt@C\͂Ƃ܂B

  logging {
          category lame-servers { null; };
          category cname { null; };
  };

  zone "." {
          type hint;
          file "/etc/bind/db.root";
  };

  ̃t@Cɂ͂̃JeSig[Nĵ킩܂B

  o  "zone"  "type" Ȃǂ WORD

  o  "/etc/bind/db.root" Ȃǂ FILENAME

  o  t@Cl[Ă QUOTE

  o  { \ OBRACE

  o  } \ EBRACE

  o  ; \ SEMICOLON

  Ή Lex t@C Example 3 ̂悤ɂȂ܂B

       %{
       #include <stdio.h>
       %}

       %%
       [a-zA-Z][a-zA-Z0-9]*    printf("WORD ");
       [a-zA-Z0-9\/.-]+        printf("FILENAME ");
       \"                      printf("QUOTE ");
       \{                      printf("OBRACE ");
       \}                      printf("EBRACE ");
       ;                       printf("SEMICOLON ");
       \n                      printf("\n");
       [ \t]+                  /* zCgXy[X͖ */;
       %%

  vOɐݒt@C͂ƁA Lex t@C
  iexample3.compile g)ȉ̂悤ȏo͂܂B

  WORD OBRACE
  WORD FILENAME OBRACE WORD SEMICOLON EBRACE SEMICOLON
  WORD WORD OBRACE WORD SEMICOLON EBRACE SEMICOLON
  EBRACE SEMICOLON

  WORD QUOTE FILENAME QUOTE OBRACE
  WORD WORD SEMICOLON
  WORD QUOTE FILENAME QUOTE SEMICOLON
  EBRACE SEMICOLON

  ݒt@CƌׂƁAK؂ 'g[N' ꂽ̂킩܂B
  t@C̊eX̕ŁAK\ɂ}b`ƂAg[Nɕϊ
  Ă܂B

  ꂪAYACC p邽߂ɕKvȂƂȂ̂łB

  3.3.  炢

  Lex ͔Cӂ̓͂Aꂼ̕ł邩肷邱ƂłA
  ƂƂ킩܂B 'g[N' Ƃ܂B

  4.  YACC

  YACC ́Alg[N\A̓Xg[̍\
  邱Ƃł܂B̂Ƃ́ALex ɑ΂ YACC ̊֌WA͂
  ƎĂ܂BYACC ͂ '̓Xg[' Ƃ̂ł
  𗝉Ă炸Ag[Nꂽ͂KvƂ܂BgŎ
  ̓vOĂǂłAł͂ Lex ɏ邱Ƃɂ
  ܂B

  @ƍ\͊ɂāA⑫Ă܂BYACC ́AoꂵĂ̍
  RpCւ̓̓t@C - ܂vO- ̍\͂ɎgĂ
  ܂BRs[^̃vO~OŏꂽvÓA
  BȂƂ *Ȃ*AӖɌĂ܂B]āAYACC ͞B
  ełAshift/reduce  reduce/reduce RtNgȂǂ̌x
  G[o܂BB YACC L "_" ɂẮA'Rt
  Ng' ̏͂B

  4.1.  Pȉxߊ

  PȌgĐł鉷xߊ킪Ƃ܂B̉xߊ
  gƂ͈ȉ̂悤ɂȂ܂B

       heat on
               Heater on!
       heat off
               Heater off!
       target temperature 22
               New temperature set!

  FȂĂ͂ȂȂg[ŃAheat, on/off(STATE), target,
  temperature, NUMBER łB

  ̎͊ Lex ō (Example 4)

       %{
       #include <stdio.h>
       #include "y.tab.h"
       %}
       %%
       [0-9]+                  return NUMBER;
       heat                    return TOKHEAT;
       on|off                  return STATE;
       target                  return TOKTARGET;
       temperature             return TOKTEMPERATURE;
       \n                      /* s͖ */;
       [ \t]+                  /* zCgXy[X͖ */;
       %%

  傫ȈႢ܂Bڂ 'y.tab.h' CN[hĂ邱
  ƂłBڂ́Aprint o͂̂߂ăg[NԂ悤ɂĂ
  ƂƂłB́ALex ̏o͂S YACC ɓ͂悤ƂĂ
  ŁAXN[ɕ\ӖȂłBy.tab.h ł̓g[N
  `Ă܂B

  y.tab.h ͂ǂoė̂ł傤H́Aō邱ƂɂȂ镶@
  t@C YACC ̂łBƓlA@ɒP
  ȂĂ܂B

       commands: /* empty */
               | commands command
               ;

       command:
               heat_switch
               |
               target_set
               ;

       heat_switch:
               TOKHEAT STATE
               {
                       printf("\tHeat turned on or off\n");
               }
               ;

       target_set:
               TOKTARGET TOKTEMPERATURE NUMBER
               {
                       printf("\tTemperature set\n");
               }
               ;

  擪̕Ał 'root' ƌĂԂƂɂ܂B 'commands' 
  ̂`ĂāAꂪʂ 'command' \Ă
  ƂĂ܂BR}hɃR}h܂ł邱ƂA
  ̋K͍ċAIłƌ܂B͂܂A\͊킪AR}
  hҌł悤ɂȂAƂƂӖĂ܂BċA
  ɂẮA'Lex  YACC ̓' ̏͂ɏdvȋLq܂B

  ̎́AR}h`KłBł́A'heat_switch' 
  'target_set' Ƃނ̂݃T|[g܂B | Lŕ\A'
  R}h heat_switch ܂ target_set 琬' ƂĂ
  B

  heat_switch ́AP 'heat' ƂPw HEAT g[NɁA
  (Lex t@C 'on'  'off' ƂĒ`ς݁jt̂łB

  target_set ͂GŁA TARGET g[N ('target' ƂP
  )ATEMPERATURE g[N ('temperature' ƂP) Đ\
  Ă܂B

  4.1.1.  YACC t@C̑S

  ÕZNVł́AYACC ̕@łAĂ
  Ƃ܂Bȉ͏ȗwb_̕łB

       %{
       #include <stdio.h>
       #include <string.h>

       void yyerror(const char *str)
       {
               fprintf(stderr,"error: %s\n",str);
       }

       int yywrap()
       {
               return 1;
       }

       main()
       {
               yyparse();
       }

       %}

       %token NUMBER TOKHEAT STATE TOKTARGET TOKTEMPERATURE

  yyerror() ֐̓G[ɁAYACC Ă΂܂Bł
  Pɗ^ꂽbZ[Wo͂܂AƂł܂B
  '֘A'̏͂B

  yywrap() ֐́AAđ̃t@Cǂݑ̂Ɏg܂B
  EOF ŌĂ΂A̃t@CI[v 0 Ԃ܂B܂
  1 ԂāAǂނׂt@C͂ȂƂƂʒm܂Bڂ
  ' Lex  YACC ̓'̏͂B

  ꂩ main() ֐܂A̓vONƂȊO
  ̂Ƃ͉Ă܂B

  ŏIśAPɎgpg[N`Ă邾łB YACC 
  -d IvVŎsɎ y.tab.h 瓾܂B

  4.1.2.  xߊ̃RpCƋN

       lex example4.l
       yacc -d example4.y
       cc lex.yy.c y.tab.c -o example4

  ȑOƈႤ_܂BYACC gĕ@t@CRpC
  邱ƂŁAy.tab.c  y.tab.h 𐶐Ă܂Bꂩ畁ʂ Lex 
  ĂяoĂ܂BRpC鎞 -ll tOOĂB
  łmain() ֐`Ă̂ŁAlibl Œ񋟂̂gKv
  ܂B

        - RpC 'yylval' ȂƂG[oꍇ́A
       example4.l  #include <y.tab.h> ̒ɁAȉLqĂB

       extern YYSTYPE yylval;

       ɂĂ 'Lex  YACC ̓' ̏͂ɐĂ܂B

  ȉ́AȒPȓłB

       $ ./example4
       heat on
               Heat turned on or off
       heat off
               Heat turned on or off
       target temperature 10
               Temperature set
       target humidity 20
       error: parse error
       $

  {ɂ肽ƂƂ͑Ă܂ÂȂwKȐH
  ƂӖłAłR[heNjbN؂ɏЉ
  ͔̂Ă܂B

  4.2.  悤ɊgAxߊ

  ܂łŁAxߊ̃R}h𐳂\͂邱Ƃł悤
  ȂłȂAG[̒ʒmK؂ɍs悤ɂȂ܂B
  AiTemperature set Ƃ悤ȁjBȌ񂵂z悤
  ɁAvOׂ͉Ă炸A[U͂ꂽl
  Ă܂B

  VK̐ݒ艷xlǂݍދ@\ǉĂ݂܂傤B邽߂
  ́A͊łǂ̂悤 NUMBER ɑ΂}b`ȂāAYACC œ
  ߂悤Ȑlɕϊ̂mKv܂B

  Lex ł́A^[QbgɃ}b`̂A'yytext' Ƃ
  Ƀ}b`eLXgi[܂BYACC ł́Al̃}b`'
  yylval' ϐ̒lǂނƂœ܂BExample 5 ͂̎łB

       %{
       #include <stdio.h>
       #include "y.tab.h"
       %}
       %%
       [0-9]+                  yylval=atoi(yytext); return NUMBER;
       heat                    return TOKHEAT;
       on|off                  yylval=!strcmp(yytext,"on"); return STATE;
       target                  return TOKTARGET;
       temperature             return TOKTEMPERATURE;
       \n                      /* s͖ */;
       [ \t]+                  /* zCgXy[X͖ */;
       %%

  ̒ʂAyytext Ƃ atoi() sAʂ YACC 
   yylval Ɋi[Ă܂BSTATE ɂĂقƂǓl̏s
  ĂA'on' Ƀ}b`镶񂪂 yylval  1 i[Ă܂B
  Lex ł 'on'  'off' ̂悤ȃ}b`͕ʁXɂƁAȃR[h
  ƂƂ͊oĂĂBł͂ƕGȋK
  āAꏏɂĂ܂B

  āAɂ YACC ł͂ǂΉΗǂ̂ł傤BLex 
  'yylval'  YACC ł͕ʂ̖OŎQƂ܂BVK̐ݒ艷xlLq
  KĂ݂܂傤B

       target_set:
               TOKTARGET TOKTEMPERATURE NUMBER
               {
                       printf("\tTemperature set to %d\n",$3);
               }
               ;

  R}h`̎OԖ (ANUMBER) ̒lɃANZXɂ́A$3 g
  ܂Byylval ̒ĺAyylex() ߂ĂxɃobt@̍Ōɒǉ
  čsA$ RXgNgŃANZXł悤ɂȂ܂B

  ڂ邽߂ɁAV 'heat_switch' ̋KĂ݂
  傤B

       heat_switch:
               TOKHEAT STATE
               {
                       if($2)
                               printf("\tHeat turned on\n");
                       else
                               printf("\tHeat turned off\n");
               }
               ;

  example5 Ă݂ĂB͂K؂Ȍ`ŏo͂͂łB

  4.3.  ݒt@C̍\

  ȑOɐGꂽݒt@C̈ꕔAxĂ݂܂傤B

       zone "." {
               type hint;
               file "/etc/bind/db.root";
       };

  ̃t@Cp̎͊͊ɍ܂BƂ YACC ̕@t@C
  A̖͊߂l YACC ł悤Ȍ`ɏC邾
  łB

  Example 6  ͊킩ȉ̂Ƃ킩܂B

  %{
  #include <stdio.h>
  #include "y.tab.h"
  %}

  %%

  zone                    return ZONETOK;
  file                    return FILETOK;
  [a-zA-Z][a-zA-Z0-9]*    yylval=strdup(yytext); return WORD;
  [a-zA-Z0-9\/.-]+        yylval=strdup(yytext); return FILENAME;
  \"                      return QUOTE;
  \{                      return OBRACE;
  \}                      return EBRACE;
  ;                       return SEMICOLON;
  \n                      /* EOL𖳎 */;
  [ \t]+                  /* zCgXy[X𖳎 */;
  %%

  Ӑ[Ă݂ƁAyylval ႤƂɋCÂł傤! lł
  Ƃ҂Ă܂񂵁A char * łƉ肵Ă܂B
  ȒPɂ邽߂ɁAQ̂\킸 strdup sĂ݂܂B
  ЂƂ̃t@Cxp[XďIAƂ悤ȈʓIȗprɂ
  ẮAŖȂƂƂoĂĂB

  ł̓t@C][̂悤ȖOłpɂɈ̂ŁA
  ƂĊi[Ƃ܂Bf[^̌̕^̈ɂĂ͌q
  ܂B

  YACC ɐV^ yylval Ăɂ́AYACC ̕@t@C̐擪
  ȉǉ܂B

  #define YYSTYPE char *

  @͍̂XɕGȂ̂ɂȂĂ܂B₷悤ɕĂ݂
  B

       commands:
               |
               commands command SEMICOLON
               ;

       command:
               zone_set
               ;

       zone_set:
               ZONETOK quotedname zonecontent
               {
                       printf("Complete zone for '%s' found\n",$2);
               }
               ;

  ́Aq̍ċAI 'root' ܂ޓłBR}h ; ŏI[
  āiċ؂āj邱ƂɗӂĂBł
  'zone_set' ƂAR}ĥݒ`܂B̃R}h ZONE g[N
  i 'zone' ƂPjƁAɑpŊꂽOA
  'zonecontent' 琬܂B܂͂ƂՂ zonecontent ł -

       zonecontent:
               OBRACE zonestatements EBRACE

   { ŕ\ OBRACE Ŏn܂܂Bꂩ zonestatementsA
   } ŕ\ EBRACE Ƒ܂B

       quotedname:
               QUOTE FILENAME QUOTE
               {
                       $$=$2;
               }

  ̃ZNV 'quotedname' `Ă܂BQUOTE ɋ܂ꂽ
  FILENAME ƂӖłAƓȂ̂́Aquotedname Ƃg[N
  ̒l FILENAME ̒lɓƂƂłB܂Aquotedname 
  t@Cp̂łƂӖłB

  ͖@ '$$=$2' R}hĂ邱ƂŁAg̒l͎g̓
  Ԗڂ̕ʂ̒lłƂƂw܂B̕@KłQƂĂ
   quotedname  $ RXgNgŃANZXƁA $$=$2 Ƃ
  ݒ肵l܂B

        - ̕@ł́A][t@C '.'  '/' ܂܂ĂȂ
       Ƃ܂s܂B

       zonestatements:
               |
               zonestatements zonestatement SEMICOLON
               ;

       zonestatement:
               statements
               |
               FILETOK quotedname
               {
                       printf("A zonefile name '%s' was encountered\n", $2);
               }
               ;

  ́A'zone' ubN̂ނ̕ɑΉł悤Ɉʉ
  łBłċAF߂܂B

       block:
               OBRACE zonestatements EBRACE SEMICOLON
               ;

       statements:
               | statements statement
               ;

       statement: WORD | block | quotedname

  ̓ubNƁA'' ̒ɏo '' `Ă܂B

  sƁAo͈͂ȉ̂悤ɂȂ܂B

       $ ./example6
       zone "." {
               type hint;
               file "/etc/bind/db.root";
               type hint;
       };
       A zonefile name '/etc/bind/db.root' was encountered
       Complete zone for '.' found

  5.  C++ ł̍\͊̍쐬

  Lex  YACC  C++ oꂷȑO炠܂AC++ ō\͊
  邱Ƃ\łBFlex ɂ C++  ͊𐶐IvV
  ܂AYACC ̕ɂ𒼐ڈ@Ȃ̂ŁAł͎gp
  ܂B

  M҂ C++ ̍\͊ۂɍDŎg@́ALex ɕʂ C t@
  C̎͊o͂āAYACC  C++ ̍\͊𐶐
  łBAvP[VNɁA̕@Ɩ肪ꍇ
  ܂BC++ ł͖I extern "C" 錾ȂAftHgł C
  ̊֐ȂłB

  邽߂ɂ́AYACC ňȉ̂悤 C wb_ĂB

  extern "C"
  {
          int yyparse(void);
          int yylex(void);
          int yywrap()
          {
                  return 1;
          }

  }

  yydebug 錾́AύXꍇ͂ňȉ̂悤ɍsĂ
  B

       extern int yydebug;

       main()
       {
               yydebug=1;
               yyparse();
       }

  ́AC++  '`͈x' K̂߂ɕKvŁAyydebug ̑d`h
  ܂B

  āAC++ ł͌^`FbN茵̂ŁAYYSTYPE  #define  Lex
  t@CɒǋLȂƂ߂܂B

  RpCɂ́Aȉ̂悤ɂĂB

       lex bindconfig2.l
       yacc --verbose --debug -d bindconfig2.y -o bindconfig2.cc
       cc -c lex.yy.c -o lex.yy.o
       c++ lex.yy.o bindconfig2.cc -o bindconfig2

  -o w肪̂ŁAy.tab.h  bindconfig2.cc.h ƂOɂȂĂ
  ƂɂӂĂB

  ܂Ƃ - ͊̃RpĆA킴킴 C++ ł낤ƂȂ C
  ł邱ƁB\͊ C++ ōAC ֐Ăяo extern
  "C" ŃRpCɐ錾邱ƁB

  6.  Lex  YACC ̓

  q YACC t@Cł́Ayyparse() Ăяo main() ֐삵܂
  Byyparse() ֐ YACC ĂAy.tab.c Ƃt@C
  Ȃ܂B

  yyparse() ́AAēׂ͂g[NƂ̒l̑gAyylex() 
  ǂݍ݂܂B̊֐͓ǎ҂삳Ă\܂񂪁ALex ɍ点
  邱Ƃł܂Bł́ALex ɂ点邱Ƃɂ܂B

  Lex 쐬 yylex() ́Ayyin Ƃ FILE * ^t@C|C^當
  ǂݍ݂܂Byyin ̓ZbgȂAftHgł͕W͂
  Ȃ܂Bo͂ yyout ɂȂAZbgĂȂ΁AftH
  gŕWo͂ƂȂ܂B܂At@C̍ŌŌĂ΂ yywrap() ֐
   yyin ύXłAʂ̃t@CI[văp[X悤ɂ
  Ƃł܂B

  ̏ꍇ́A0 ߂lƂĕԂ悤ɂĂBp[XI
  ́A1 Ԃ悤ɂĂB

  yylex() ͌Ă΂xɁAg[Nʂ\lԂ܂B
  YACC A܂܂łɂǂȃg[Nǂݍ񂾂̂Ɏg
  Bg[N͐ӁAlꍇȀꍇ yylval ɒli[
  ܂B

  ftHgł́Ayylval  int ^łAYACC t@Cōēx YYSTYPE 
  #define 邱ƂŁAI[o[Ch邱Ƃł܂B

  ͊́Ayylval ɃANZXłKv܂B̂߂ɂ́A
  yylval ͊̃XR[vɑ΂āAOQƕϐƂĐ錾Ă
  Kv܂BIWi YACC ́AIɂĂȂ
  ŁAȉ͊ #include <y.tab.h> ɁALqKv
  B

  extern YYSTYPE yylval;

  ߔNLgĂ Bison ł́AIɂĂ܂B

  6.1.  g[N̒l

  q悤ɁAyylex() ͏og[NʂԂKvAl
  yylval Ɋi[Kv܂B̃g[NA%token R}h
  `ĂꍇAeXɂ 256 n܂鐔 id UĂ
  B

  ̂ƂASAXL[g[NƂ邱Ƃ\łBႦ΁Ad
  ꍇȂǁA܂ł̌o𐶂ƁAȉ̂悤Ɏ͊
  邱ƂɂȂł傤B

  [0-9]+          yylval=atoi(yytext); return NUMBER;
  [ \n]+          /* eat whitespace */;
  -               return MINUS;
  \*              return MULT;
  \+              return PLUS;
  ...

  YACC @ɂ́Aȉ܂ނƂɂȂ܂F

               exp:    NUMBER
                       |
                       exp PLUS exp
                       |
                       exp MINUS exp
                       |
                       exp MULT exp

  ͖ʂɕGȂłBl\g[N id AgĊ
  \LƁA͈͊ȉ̂悤ɏ܂:

  [0-9]+          yylval=atoi(yytext); return NUMBER;
  [ \n]+          /* eat whitespace */;
  .               return (int) yytext[0];

  Ō̃hbǵA}b`ȂSĂ\܂B

  AYACC@

               exp:    NUMBER
                       |
                       exp '+' exp
                       |
                       exp '-' exp
                       |
                       exp '*' exp

  킩₷A܂ZȂ܂BAXL[\g[Nwb
  _ %token Ő錾KvȂÂ܂܂ŎgĂ܂B

  ̃RXgNĝЂƂDꂽƂ́A͂̂͂Ȃł
  Lex }b`ƂĂ悤ɂȂAƂƂł - 邱
  ŁA}b`Ȃ͂Wo͂֓foƂAftHg
  Ă܂BႦ΁AdɃ[U ^ ͂ƁAWo͂ւ̂܂ܕ\
  ɍ\̓G[o͂悤ɂȂ܂B
  6.2.  ċA - 'P(right=Ej͈'

  ċÁAYACC ł͂߂ďdvłBȂẮAƗR}h
  ̘At@C\ĂAƂƂȂȂ܂B
  ܂AYACC ɂƂčłdvȂ͈̂Ԗڂ̋KAA'%start' V{
  Ŏw肵AN_K݂̂ƂƂɂȂ܂B

  YACC ɂċAɂ́A2̃^Cv - Eƍ - ܂BċA͂ق
  ǂ̏ꍇɎĝׂŁAȉ̂悤Ȃ̂łB

  commands: /* empty */
          |
          commands command

  ́AR}hłÃ͕R}ȟɁAR}h
  ƂӖłBYACC ̓삩炷ƁÁiOjX
  R}hQȒPɐ؂蕪āAҌłƂƂӖ܂B

  EċAƔׂĂ݂ƁA킵łڂ͗ǂȂ܂B

  commands: /* empty */
          |
          command commands

  A͏ƂĂ͍܂B%start KƂĎgꂽ
  AYACC ̓t@C̑SR}hX^bNɕێȂĂ͂Ȃ炸A
  ʂɏ܂B̂ƂAt@CSƂ悤Ȓ̍\
  ͂ۂ́AċAgpĂBɂ͉EċA̎gp
  Ȃ悤ȏ󋵂邩܂񂪁A܂ɂꍇ
  ẮAċAȊOgKv͂Ȃł傤B

  R}hI[āi䂦ɋ؂āĵ悤ȏꍇɂ́AE
  AgƎRȊɂȂ܂AƂɂ͂肠܂
  B

  commands: /* empty */
          |
          command SEMICOLON commands

  ̃R[h́A͍ċAgď܂iM҂ł
  ł͂܂jB

  commands: /* empty */
          |
          commands command SEMICOLON

   HOWTO ̈ȑÕo[WłAԈႦĉEċAgĂ܂A
  Markus Triska e؂ɂwEĂ܂B

  6.3.  荂x yylval - %union

  ܂łł́Ayylval  *^̂* `Kv܂B
  AꂪKłƂ͌܂B̃f[^^ȂĂ
  ȂȂƂ邩mȂłBzxߊ̗ɖ߂āA
  䂷ׂq[^[IтƂAȉ̂悤ɂȂ܂B

       heater mainbuiling
               Selected 'mainbuilding' heater
       target temperature 23
               'mainbuilding' heater target temperature now 23

  |Cg yylval p̂ɂȂāAƐ̗ێ邱Ƃ
  łAƂƂł - Ɉꏏł͂܂񂪁B

  ȑOAYACC ɑ΂ yylval ̌^AYYSTYPE ƂĒ`Ă̂v
  oĂB́AYACC  %union ƂAȒPȕ@ŁA
  p̂ƂĒ`邱Ƃł̂ł͂Ȃł傤B

  Example 4 ɊÂāAExample 7  YACC @Ă݂܂B܂͂
   -

       %token TOKHEATER TOKHEAT TOKTARGET TOKTEMPERATURE

       %union
       {
               int number;
               char *string;
       }

       %token <number> STATE
       %token <number> NUMBER
       %token <string> WORD

  ƕ݂̂܂ށAp̂`܂Bꂩgꂽ %token
  V^bNXŁAYACC ɋp̂̂ǂ̕ɁAꂼ̃g[NANZ
  XׂwĂ܂B

  ̏ꍇAȑO悤 STATE g[N int ^蓖Ă܂Bl
  ɁAxǂݎ邽߂ NUMBER g[N蓖Ă܂B

  V̂ WORD g[NŁAłƐ錾Ă܂B

  ̓vÕt@CAύX܂B

       %{
       #include <stdio.h>
       #include <string.h>
       #include "y.tab.h"
       %}
       %%
       [0-9]+                  yylval.number=atoi(yytext); return NUMBER;
       heater                  return TOKHEATER;
       heat                    return TOKHEAT;
       on|off                  yylval.number=!strcmp(yytext,"on"); return STATE;
       target                  return TOKTARGET;
       temperature             return TOKTEMPERATURE;
       [a-z0-9]+               yylval.string=strdup(yytext);return WORD;
       \n                      /* s͖ */;
       [ \t]+                  /* zCgXy[X͖ */;
       %%

  CÂɂȂ悤ɁA yylval ̂̂ɂ͒ڃANZXĂ
  AANZX̂ɁATtBbNXtĂ܂BYACC
  ɂ͈ȉ̂悤Ȗ@̂ŁAYACC @ł͕͂svłB

       heater_select:
               TOKHEATER WORD
               {
                       printf("\tSelected heater '%s'\n",$2);
                       heater=$2;
               }
               ;

  Oq %token 錾̂ŁAYACC ͎Iɋp̂ '' 
  oǂݎĂĂ܂B܂Ał͌ŁAR}h̑ɂȂ
  Ăq[^[[Uɒʒm̂ɎgA$2 ̃Rs[i[Ă
  ܂B

       target_set:
               TOKTARGET TOKTEMPERATURE NUMBER
               {
                       printf("\tHeater '%s' temperature set to %d\n",heater,$3);
               }
               ;

  ڍׂ example7.y QƂB

  7.  fobO

  vOAȂwԂ悤Ȏ͓ɁAfobO@\邱Ƃ
  dvɂȂ܂BK^ɂYACĆÃtB[hobNԂ@\
  ܂B̋@\͂炩I[o[wbhKvƂ̂ŁAgpɂ
  Ă͊̃XCb`Cl[uɂKv܂B

  @RpC鎞́AYACC ̃R}hCɁA--debug 
  --verbose ܂B@t@C C wb_ɂ́Aȉt
  B

  int yydebug=1;

   'y.output' ƂAo͂ꂽXe[g}Vt@C
  ܂B

  ꂽoCisƁÃt@ĆA݋NĂ邱Ƃ
  āA*ɂ* o͂Ă܂Bɂ́AXe[g
  }VǂȃXe[gۗLĂ̂Aǂȃg[Nǂݍ܂
  ̂̏܂܂܂B

  Peter Jinks debugging
  <http://www.cs.man.ac.uk/~pjj/cs2121/debug.html> ɂ悭G[A
  G[ւ̑Ώ̎dȂǂڂĂ܂B

  7.1.  Xe[g}V

  YACC Ő\͊́AIɂ 'Xe[g}V' Ƃ̂
  sĂ܂BO悤ɁÁA̃Xe[giԁj
  Ƃ蓾}Vi@BĵƂłBǂ̃Xe[gǂ̃Xe[g֑Jڂ
  邩肷KAƂ݂̂܂BSĂ͕M҂OqA
   'root' KN_ƂȂ܂B

  Example 7  y.output ̏o͂p -

       state 0

           ZONETOK     , and go to state 1

           $default    reduce using rule 1 (commands)

           commands    go to state 29
           command     go to state 2
           zone_set    go to state 3

  ̃Xe[ǵAftHgł 'commands' KpĊҌ܂B
  ́AOqċAɊւKłAX̃R}hAZ~RAX
  R}h\ 'commands' `Ă܂B

  ̃Xe[ǵA߂łg[N - ̏ꍇ ZONETOK  'zone' Ƃ
  P - ɓB܂ŊҌ܂BꂩAXe[g 1 ֑JڂAzone
  R}hɏڂ܂B

       state 1

           zone_set  ->  ZONETOK . quotedname zonecontent   (rule 4)

           QUOTE       , and go to state 4

           quotedname  go to state 5

  ŏ̍s݂͌̏ꏊ '.' ܂ł܂ - ZONETOK ͊Ɍ
  ̂ŁA 'quotedname' TĂ܂Bquotedname  QUOTE Ŏn܂
  ̂ŁAXe[g 4 ɑJڂ邱ƂɂȂ܂B

  ȏɂĂ@艺́AExample 7 fobȌ͂ŐGꂽ
  tOtăRpCĂ݂ĂB

  7.2.  RtNg: 'shift/reduce', 'reduce/reduce'

  YACC RtNgɂČxóA肪鎞ł傤B
  RtNgƂɂ́AƂɐEl|̂悤ȓꂳA
  ̎gpĂ錾ɂđ̂ƂĂ邱Ƃł傤 - 
  Ȃm肽ƈȏ̂ƂB

  ́AAg[Nǂ߂邩AƂ_𒆐SɋN܂B
  ȉ̓̃R}h󂯕tKv錾A`Ƃ܂
  B

               delete heater all
               delete heater number1

  ɂ́Aȉ̕@`KvłB

          delete_heaters:
                  TOKDELETE TOKHEATER mode
                  {
                          deleteheaters($3);
                  }

          mode:   WORD

          delete_a_heater:
                  TOKDELETE TOKHEATER WORD
                  {
                          delete($3);
                  }

  ̏LĂ܂ˁBXe[g}V 'delete' ƂP
  ǂނƂn߂āÃg[Nł邩ɂāAJڐ肷
  Kv܂B̃g[NƂ̂́Aq[^[̍폜@w肷
  [hA͍폜ׂq[^[̖OłB

  ͗̃R}hɂƂāÃg[N WORD ɂȂƂƂ
  B YACC ́Ȁꍇǂėǂ킩܂Bꂪ
  'reduce/reduce'AXɂ 'delete_a_heater' m[hɌĒB邱Ƃ
  AƂxɂȂ܂B

  ̏ꍇ̃RtNǵAȒPɉł܂iŏ̃R}h'
  delete heaters all' ɕύXA'all' Ɨg[NƂĒ`
  ȂǁjAƕGɂȂ邱Ƃ܂B--verbose tOt
  yaccʂƐ y.output t@ĆAȎɔɏƂ
  ܂B

  8.  ֘A

  GNU YACC (Bison) ɂ́AYACC ̃V^bNXڂLq΂炵
  info t@C (.info) tĂ܂BLex ͈xGĂ܂
  񂪁A̓_ΗDĂ܂B.info t@C Emacs  'pinfo' 
  Ag̗ǂc[œǂނƂł܂Bȉ GNU TCg
  \łFBISON Manual <http://www.gnu.org/manual/bison/>.

  Flex ɂ͗Dꂽ man y[WtĂ܂BFlex ŉł邩A
  ƂłĂlɂ́AƂĂLpł傤BFlex Manual
  <http://www.gnu.org/manual/flex/> ICœ\łB

   Lex  YACC ̃Cg_NVIāA񂪗~
  vꂽł傤Bȉ̖{́AM҂͑Sǂł܂񂪁A^C
  g͂ł -

     Bison-The Yacc-Compatible Parser Generator

        Charles Donnelly and Richard Stallman ɂ̂łB̖{C
        ɓAmazon
        <http://www.amazon.com/exec/obidos/ASIN/0595100325/qid=989165194/sr=1-2/ref=sc_b_3/002-7737249-1404015>
        [U悤łB

     Lex & Yacc

        John R. Levine, Tony Mason and Doug Brown ɂ̂łB
        ƌÂłÃe[}ɊւĂ͋ȏI݂łBAmazon
        <http://www.amazon.com/exec/obidos/ASIN/1565920007/ref=sim_books/002-7737249-1404015>
        Ƀr[܂B

     Compilers : Principles, Techniques, and Tools

        Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman ɂ̂łB
         'hSubN'B1985NɏoƂ̂ɁA񂦂Ƒ
        Ă܂BRpCJɊւĂ͋ȏI݂łBAmazon
        <http://www.amazon.com/exec/obidos/ASIN/0201100886/ref=sim_books/002-7737249-1404015>

  Thomas Niemann  Lex  YACC gRpCƓd̍ɂ
  hLgĂA <http://epaperpress.com/y_man.html>ɂ
  ܂B

  comp.compilers Ƃj[XO[v usenet ɂAȂȂp
  l܂BłAQĂl͍\͊̐ꑮwvfXN
  vł͂܂! eOɁAނ̃y[W
  <http://compilers.iecc.com/>͋[̂Ō邱ƁAɎ FAQ
  <http://compilers.iecc.com/faq.txt>ɂƖڂʂœ邱
  ƁB

  Lex - A Lexical Analyzer Generator by M. E. Lesk and E. Schmidt ͕M
  phLĝЂƂłB
  <http://www.cs.utexas.edu/users/novak/lexpaper.htm>œł܂B

  Yacc: Yet Another Compiler-Compiler by Stephen C. Johnson ͕M҂
  YACC ɂĈphLg̈łB
  <http://www.cs.utexas.edu/users/novak/yaccpaper.htm>œł܂BX
  ^CɂẴqgڂĂ܂B

  9.  ӎ

  o  Pete Jinks <pjj@cs.man.ac.uk>

  o  Chris Lattner <sabre@nondot.org>

  o  John W. Millaway <johnmillaway@yahoo.com>

  o  Martin Neitzel <neitzel@gaertner.de>

  o  Esmond Pitt <esmond.pitt@bigpond.com>

  o  Eric S. Raymond

  o  Bob Schmertz <schmertz@wam.umd.edu>

  o  Adam Sulmicki <adam@cfar.umd.edu>

  o  Markus Triska <triska@gmx.at>

  o  Erik Verbruggen <erik@road-warrior.cs.kun.nl>

  o  Gary V. Vaughan <gary@gnu.org> (read his awesome Autobook
     <http://sources.redhat.com/autobook>)

  o  Ivo van der Wijk <http://vanderwijk.info> ( Amaze Internet
     <http://www.amaze.nl>)

  : |ɂẮAR`VAщTɗLvȃRg
  ܂B肪Ƃ܂B

