Provided by: manpages-pl_20060617-3_all bug

NAZWA

       flex - szybki generator analizatora leksykalnego

SK/LADNIA

       flex [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton]
       [--help --version] [filename ...]

WPROWADZENIE

       Podrcznik  ten  opisuje  narzdzie  flex.   Jest  ono  przeznaczone   do
       generowania  programow,  dokonywujcych dopasowywania wzorcow na tekcie.
       Podrcznik zawiera zarowno sekcje przewodnikowe jak i informacyjne.

           Opis
            krotki przegld moliwoci narzdzia

           Proste Przyklady

           Format Pliku Wejciowego

           Wzorce
            rozszerzone wyraenia regularne uywane przez flex

           Sposob Dopasowywania Wejcia
            reguly okrelania, co dopasowano

           Akcje
            jak podawa, co robi po dopasowaniu wzorca

           Generowany Skaner
            szczegoly o skanerze, tworzonym przez fleksa; jak kontrolowa rodlo
            wejciowe

           Warunki Startowe
               wprowadzanie do skanerow kontekstu i obsluga "mini-skanerow"

           Wielokrotne Bufory Wejciowe
            jak obslugiwa wiele rodel wejciowych; jak skanowa z lacuchow
            zamiast z plikow

           Reguly Koca Pliku
            specjalne reguly dopasowywane do koca wejcia

           Rone Makra
            ogol makr dostpnych z poziomu akcji

           Wartoci Dostpne Uytkownikowi
            ogol wartoci dostpnych z poziomu akcji

           Lczenie z Yacc
            lczenie skanerow flex z analizatorami yacc

           Opcje
            opcje linii polece fleksa i dyrektywa "%option"

           Kwestie wydajnociowe
            jak przyspiesza skanery

           Generowanie Skanerow C++
            eksperymentalna wlaciwo generowania klas skanerow C++

           Niezgodnoci z Lex i POSIX
            czym flex roni si od standardow AT&T lex i POSIX lex

           Diagnostyka
            objanienie komunikatow o bldach, generowanych przez flex (lub
            skanery)

           Pliki
            pliki uywane przez flex

           Niedostatki / Bldy
            znane problemy fleksa

           Zobacz Take
            pozostala dokumentacja i zwizane z fleksem narzdzia

           Autor
            informacja kontaktu z autorem

OPIS

       flex jest narzdziem przeznaczonym do generowania  skaner'ow:  programow,
       rozpoznajcych  wzorce  leksykalne  tekstu.  flex odczytuje podane pliki
       wejciowe  (lub  stdin  gdy  nie  s  podane)  i  pobiera  z  nich   opis
       generowanego  skanera. Opis sklada si z par wyrae regularnych i kodu C.
       Pary te nazywane s regu/lami.  flex jako wyjcie generuje plik rodlowy  C
       o  nazwie  lex.yy.c.   Definiuje  on  funkcj  yylex().   Plik  ten musi
       kompilowany i konsolidowany z bibliotek -lfl.   Po  uruchomieniu  pliku
       wykonywalnego,   program   analizuje   wejcie   w   poszukiwaniu  wyrae
       regularnych. Gdy tylko takie si znajdzie,  wykonywany  jest  odpowiedni
       fragment kodu C.

PROSTE PRZYK/LADY

       Przedstawmy teraz troch prostych przykladow aby oby si z uywaniem flex.
       Nastpujcy plik wejciowy flex okrela skaner, ktory za  kadym  razem  gdy
       napotka lacuch "username", podmieni go nazw uytkownika:

           %%
           username    printf( "%s", getlogin() );

       Domylnie tekst, ktorego flex nie moe dopasowa jest kopiowany na wyjcie.
       Skaner bdzie wic kopiowal swoj plik  wejciowy  na  wyjcie,  podmieniajc
       wszelkie  pojawienia  "username".   W tym przykladzie wejcia mamy tylko
       jedn regul. Wzorcem jest "username", a akcj jest "printf".  Znaki  "%%"
       oznaczaj pocztek regul.

       Oto kolejny prosty przyklad:

                   int num_lines = 0, num_chars = 0;

           %%
           \n      ++num_lines; ++num_chars;
           .       ++num_chars;

           %%
           main()
                   {
                   yylex();
                   printf( "# of lines = %d, # of chars = %d\n",
                           num_lines, num_chars );
                   }

       Ten skaner zlicza liczb znakow i liczb linijek swojego wejcia (nie daje
       adnego wyjcia, nie liczc kocowego raportu).  Pierwsza  linia  deklaruje
       dwie  zmienne  globalne,  "num_lines"  i  "num_chars",  ktore s dostpne
       wewntrz funkcji yylex() i main(), zadeklarowanej po drugim  "%%".  Mamy
       tu  dwie  reguly:  pierwsza  dopasowuje  si  do  nowej  linii  ("\n") i
       inkrementuje  licznik  linii  oraz  znakow;  druga  dopasowuje  si   do
       dowolnego znaku innego ni nowa linia (wyraenie regularne ".") i zwiksza
       licznik liczby znakow.

       A oto troch bardziej skomplikowany przyklad:

           /* skaner dla zabawkowego Pascalo-podobnego jzyka */

           %{
           /* potrzebujemy tego do wywolania atof() */
           #include <math.h>
           %}

           DIGIT    [0-9]
           ID       [a-z][a-z0-9]*

           %%

           {DIGIT}+    {
                       printf( "Liczba calkowita: %s (%d)\n", yytext,
                               atoi( yytext ) );
                       }

           {DIGIT}+"."{DIGIT}*        {
                       printf( "Liczba zmiennoprzecinkowa: %s (%g)\n", yytext,
                               atof( yytext ) );
                       }

           if|then|begin|end|procedure|function        {
                       printf( "Slowo kluczowe: %s\n", yytext );
                       }

           {ID}        printf( "Identyfikator: %s\n", yytext );

           "+"|"-"|"*"|"/"   printf( "Operator: %s\n", yytext );

           "{"[^}\n]*"}"     /* zjedz jednolinijkowe komentarze */

           [ \t\n]+          /* zjedz biale spacje */

           .           printf( "Nierozpoznany znak: %s\n", yytext );

           %%

           main( argc, argv )
           int argc;
           char **argv;
               {
               ++argv, --argc;  /* pomi nazw programu */
               if ( argc > 0 )
                       yyin = fopen( argv[0], "r" );
               else
                       yyin = stdin;

               yylex();
               }

       S to pocztki prostego skanera dla jzyka podobnego do Pascala.  Rozronia
       poszczegolne rodzaje token'ow i informuje co zobaczyl.

       Szczegoly tego przykladu zostan wyjanione w nastpnych sekcjach.

FORMAT PLIKU WEJCIOWEGO

       Plik wejciowy fleksa sklada si z trzech sekcji, rozdzielanych liniami z
       lacuchem %%:

           definicje
           %%
           reguly
           %%
           kod uytkownika

       Sekcja definicji zawiera definicje prostych nazw, upraszczajcych poniej
       specyfikacj  skanera. Zawiera te deklaracje warunk'ow pocztkowych, ktore
       objaniono w dalszej sekcji.

       Definicje nazw maj posta:

           nazwa definicja

       gdzie "nazwa" jest slowem, rozpoczynajcym si od litery lub  podkrelenia
       ('_').   Pozostale  znaki  mog  by literami, cyframi, podkreleniami lub
       mylnikami.   Definicja  jest  pobierana  od   momentu   pojawienia   si
       pierwszego  znaku,  ktory  nie  jest spacj i ktory znajduje si za nazw.
       Definicja rozciga si  do  koca  linii.  Do  takiej  definicji  mona  si
       nastpnie   odwolywa   przy   uyciu   konwencji  "{nazwa}",  ktora  jest
       automatycznie rozwijana w "(definicj)". Na przyklad

           DIGIT    [0-9]
           ID       [a-z][a-z0-9]*

       definiuje "DIGIT"  jako  wyraenie  regularne,  pasujce  do  pojedynczej
       cyfry,   a   "ID"   jako  wyraenie  regularne  odpowiadajce  literze  z
       doklejonymi ewentualnymi literami lub cyframi.   Poniejsze  odniesienie
       do

           {DIGIT}+"."{DIGIT}*

       jest rownowane

           ([0-9])+"."([0-9])*

       i  dopasowuje  jedn  lub  wicej  cyfr,  po  ktorych  wystpuje  kropka i
       ewentualnie nastpne cyfry.

       Sekcja regu/l wejcia fleksa zawiera szereg regul w postaci:

           wzorzec   akcja

       Przed wzorcem nie moe wystpi wcicie, a akcja musi rozpoczyna si  w  tej
       samej linii.

       Dla dalszego opisu akcji patrz dalej.

       W  kocu,  sekcja  kodu uytkownika jest zwyczajnie kopiowana do lex.yy.c
       (bez  dokonywania  w  niej  zmian).   Jest   to   uywane   do   funkcji
       pomocniczych,  ktore wolaj lub s wolane przez skaner. Obecno tej sekcji
       jest opcjonalna; jeli nie istnieje, to ostatni %% pliku wejciowego  moe
       by pominity.

       Jeli   w   sekcjach   definicji   lub  regul  znajduje  si  jaki  wcity
       (indentowany) tekst lub tekst ujty w %{ i  %},  to  jest  on  kopiowany
       doslownie  na  wyjcie  (po  usuniciu  %{}).   Znaki  %{} musz pojawi si
       samodzielnie w liniach bez wci.

       W sekcji regul, tekst wcity lub tekst %{}, znajdujcy si  przed  pierwsz
       regul moe sluy deklarowaniu zmiennych lokalnych dla procedury skanujcej
       oraz  (po  deklaracjach)  kodu,  ktory  ma  by  wywolywany   za   kadym
       uruchomieniem  procedury skanujcej.  Pozostale przypadki wcitego tekstu
       lub tekstu %{} sekcji regul s  nadal  kopiowane  na  wyjcie,  lecz  ich
       znaczenie   nie  jest  dokladnie  zdefiniowane  i  mog  spowodowa  bldy
       kompilacji (wlaciwo ta jest obecna dla zgodnoci z  POSIX;  zobacz  niej
       inne tego typu wlaciwoci).

       W  sekcji  definicji  na  wyjcie  kopiowane  s  rownie  nie-wcite bloki
       komentarza, ujte midzy znaki "/*" i "*/".

WZORCE

       Wzorce  wejciowe  s  pisane  z  uyciem  rozszerzonego   zestawu   wyrae
       regularnych. S to:

           x          dopasowuje znak 'x'
           .          dowolny znak poza now lini
           [xyz]      "klasa znakow"; w tym przypadku wzorzec odpowiada
                        zarowno 'x', 'y' jak i 'z'
           [abj-oZ]   "klasa znakow" z zakresem; odpowiada ona
                        'a', 'b', dowolnej literze od 'j' do 'o' oraz 'Z'
           [^A-Z]     zanegowana "klasa znakow" tj. dowolny znak poza
                        wymienionymi w klasie. W tym wypadku dowolny znak oprocz
                  duych liter
           [^A-Z\n]  dowolny znak oprocz duych liter lub nowej linii
           r*         zero lub wicej r'ow, gdzie r jest wyraeniem regularnym
           r+         jeden lub wicej r'ow
           r?         zero lub jeden r (tj. "opcjonalny r")
           r{2,5}     od dwu do piciu r
           r{2,}      dwa lub wicej r
           r{4}       dokladnie 4 r
           {nazwa}    rozwinicie definicji "nazwa" (patrz wyej)
           "[xyz]\"foo"
                      lacuch literalny: [xyz]"foo
           \X        Jeli X to 'a', 'b', 'f', 'n', 'r', 't' lub 'v',
                  to nastpuje interpretacja ANSI-C \x. W przeciwnym
                  wypadku uywany jest literalny 'X' (uywane do cytowania
                  operatorow--np. '*').
           \0        znak NUL (kod ASCII 0)
           \123      znak o wartoci osemkowej 123
           \x2a      znak o wartoci szesnastkowej 2a
           (r)        dopasuj r; nawiasy s uywane do przeciania priorytetow
                     (patrz niej)

           rs         wyraenie regularne r, za ktorym nastpuje wyraenie
                  regularne s; nazywa si to "lczeniem"

           r|s        r lub s

           r/s        r, lecz tylko jeli za nim nastpuje s. Tekst dopasowywany
                  przez s jest zalczany do okrelania czy ta regula miala
                  "najdlusze dopasowanie", lecz potem jest zwracany do
                  wejcia przed wykonaniem akcji. Tak wic akcja widzi tylko
                  tekst dopasowany przez r. Ten rodzaj wzorca jest nazywany
                  "doklejonym kontekstem". (Istniej pewne kombinacje r/s,
                  ktorych flex nie potrafi wlaciwie dopasowa; zobacz uwagi
                  w dalszej sekcji Niedostatki / Bldy w okolicach
                  "niebezpiecznego kontekstu doklejonego".)
           ^r         r, lecz tylko na pocztku linii (tj. zaraz po rozpoczciu
                  skanowania, lub po wyskanowaniu nowej linii).
           r$         r, lecz tylko na kocu linii (tj. tu przed now lini).
                  Rownowane "r/\n".

                   Zauwa, e notacja nowej linii fleksa jest dokladnie tym,
                   co bylo uywane jako '\n' przez kompilator C, uyty do
                   kompilacji fleksa; w praktyce na niektorych systemach DOS
                   musisz wyfiltrowa \r lub jawnie uywa r/\r\n zamiast
                   "r$".

           <s>r       r, lecz tylko dla warunku pocztkowego s (zobacz niej
                  dyskusj o warunkach pocztkowych)
           <s1,s2,s3>r
                      to samo, lecz jeli dowolny z warunkow pocztkowych s1,
                        s2 lub s3
           <*>r       r w dowolnym warunku pocztkowym, nawet wykluczajcym

           <<EOF>>    koniec pliku
           <s1,s2><<EOF>>
                      koniec pliku w warunkach pocztkowych s1 lub s2

       Zauwa,  e  w  obrbie klasy znakow wszystkie operatory wyrae regularnych
       trac swoje znaczenie specjalne (nie liczc cytowania '\',  znakow  klasy
       '-', ']' oraz '^' na pocztku klasy).

       Wymienione   wyej   wyraenia   regularne   s   pogrupowane   zgodnie  z
       priorytetami, liczc od najwyszego do najniszego (z gory  na  dol).  Te,
       ktore zgrupowano razem maj jednakowy priorytet. Na przyklad,

           foo|bar*

       jest rownowane

           (foo)|(ba(r*))

       poniewa  operator '*' ma wyszy priorytet ni lczenie, a lczenie ma wyszy
       priorytet ni alternatywa ('|'). Wzorzec ten pasuje wic albo do  lacucha
       "foo"  albo  do  "ba",  po  ktorym moe nastpi zero lub wicej r.  W celu
       dopasowania "foo" lub zero lub wicej "bar"'ow, uyj:

           foo|(bar)*

       a eby dopasowa zero lub wicej "foo"-lub-"bar"'ow:

           (foo|bar)*

       Poza znakami i zakresami znakow, klasy znakow mog te zawiera  specjalne
       wyraenia.   Wyraenia  te  s ujmowane w ograniczniki [: i :] (ktore musz
       dodatkowo pojawia si wewntrz '[' i ']' klasy znakow;  inne  elementy  w
       klasie znakow te mog si pojawi).  Prawidlowymi wyraeniami s:

           [:alnum:] [:alpha:] [:blank:]
           [:cntrl:] [:digit:] [:graph:]
           [:lower:] [:print:] [:punct:]
           [:space:] [:upper:] [:xdigit:]

       Wyraenia   te   oznaczaj   zestaw   znakow,   odpowiadajcy  rownowanemu
       standardowi  funkcji  isXXX  jzyka  C.  Przykladowo  [:alnum:]  oznacza
       wszystkie  znaki,  dla  ktorych  isalnum(3) zwraca prawd - tj. wszelkie
       znaki alfabetyczne lub numeryczne.   Niektore  systemy  nie  udostpniaj
       isblank(3).  Flex definiuje [:blank:] jako spacj lub tabulacj.

       Na przyklad nastpujce klasy s sobie rownowane:

           [[:alnum:]]
           [[:alpha:][:digit:]
           [[:alpha:]0-9]
           [a-zA-Z0-9]

       Jeli twoj skaner jest niewraliwy na wielko znakow (flaga (flaga -i), to
       [:upper:] i [:lower:] s rownowane [:alpha:].

       Troch uwag o wzorcach:

       -      Zanegowana klasa znakow, taka jak  wyej  wymienione  przykladowe
              "[^A-Z]"  bdzie  pasowa  do  nowej  linii,  chyba  e  "\n"  (lub
              rownowana sekwencja specjalna) jest jednym z jawnie  obecnych  w
              klasie   znakow   (np.   "[^A-Z\n]").   Odbiega  to  od  sposobu
              traktowania  zanegowanych  klas  znakow  przez   inne   narzdzia
              operujce na wyraeniach regularnych, lecz niestety niespojno jest
              ugruntowana historycznie.  Dopasowywanie nowej linii oznacza,  e
              wzorzec  w rodzaju [^"]* moe dopasowa si do calego wejcia, chyba
              e istnieje w nim drugi cudzyslow.

       -      Regula  moe  mie  najwyej  jedn  instancj  dowizanego  kontekstu
              (operatory  '/'  lub  '$').  Wzorce warunku pocztkowego '^' oraz
              "<<EOF>>" mog pojawi si tylko na  pocztku  wzorca  i  dodatkowo,
              podobnie  jak  '/'  i  '$', nie mog by grupowane w nawiasy. Znak
              '^', ktory nie pojawia  si  na  pocztku  reguly,  lub  '$',  nie
              znajdujcy si na kocu traci swoje specjalne znaczenie.

              Nastpujce wzorce s niedozwolone:

                  foo/bar$
                  <sc1>foo<sc2>bar

              Zauwa, e pierwszy z nich moe by zapisany jako "foo/bar\n".

              Nastpujce  wzorce powoduj, e '$' lub '^' s traktowane jak zwykle
              znaki:

                  foo|(bar$)
                  foo|^bar

              Jeli oczekiwan wartoci jest "foo" lub  "bar-z-now-lini",  to  uy
              mona nastpujcego wzorca (akcja specjalna | jest wyjaniona niej):

                  foo      |
                  bar$     /* tu rozpoczyna si akcja */

              Podobna sztuczka powinna zadziala dla dopasowywania foo lub bar-
              na-pocztku-linii.

JAK DOPASOWYWANE JEST WEJCIE

       Po uruchomieniu skanera,  analizuje  on  swoje  wejcie  w  poszukiwaniu
       lacuchow  odpowiadajcych ktoremu z jego wzorcow. Jeli znajdzie wicej ni
       jeden pasujcy wzorzec, wybiera ten, ktory pasuje  do  najwikszej  iloci
       tekstu  (w  regulach  z  dowizanym  kontekstem oznacza to te dlugo czci
       dowizanej, mimo faktu, e zostanie ona zwrocona na wejcie. Jeli znajdzie
       dwa  lub wicej dopasowa o tej samej dlugoci, to wybierana jest pierwsza
       regula.

       Po okreleniu dopasowania, tekst dopasowania (zwany dalej tokenem)  jest
       udostpniany  we  wskanikowej  zmiennej globalnej yytext, a jego dlugo w
       globalnej zmiennej calkowitej yyleng.  Wykonywana jest te  odpowiadajca
       wzorcowi   akcja  (szczegolowy  opis  akcji  jest  dalej),  a  nastpnie
       pozostala cz wejcia jest dopasowywana do kolejnego wzorca.

       Jeli dopasowanie nie  zostanie  znalezione,  wykonana  zostanie  regu/la
       domylna:  nastpny  znak wejcia jest uwaany za dopasowany i kopiowany na
       stdout.  Tak wic najprostszym poprawnym plikiem wejciowym fleksa jest:

           %%

       Generuje to skaner, ktory po prostu kopiuje swoje  wejcie  (jeden  znak
       naraz) na wyjcie.

       Zauwa,  e  yytext  moe  by  definiowane na dwa sposoby: jako wskanik do
       znakow lub jako tablica  znakow.   Uywanie  konkretnej  definicji  mona
       kontrolowa,  wlczajc  do  pliku wejciowego w pierwszej sekcji specjalne
       dyrektywy  %pointer  lub  %array.   Domylnie  uywana   jest   dyrektywa
       %pointer,  chyba  e  uywa  si opcji -l zgodnoci z leksem i wtedy yytext
       staje si tablic.  Korzyci z uywania %pointer jest  zwikszenie  szybkoci
       skanowania  i  zlikwidowanie przepelnie bufora przy dopasowywaniu duych
       tokenow (chyba e zabraknie pamici dynamicznej).  Wad jest  ograniczenie
       sposobu modyfikowania przez akcje zmiennej yytext (zobacz nastpn sekcj)
       i to, e wywolania funkcji unput() niszcz aktualn zawarto yytext, co moe
       przyprawia  o  bol  glowy  podczas  portowania  skanerow  midzy  ronymi
       wersjami lex.

       Zalet %array jest moliwo modyfikowania yytext i to, e  wolanie  unput()
       nie   niszczy   yytext.   Poza  tym,  istniejce  programy  lex  czasami
       zewntrznie zagldaj do yytext przy uyciu deklaracji w postaci:
           extern char yytext[];
       Definicja ta jest bldna przy uyciu  z  %pointer,  lecz  prawidlowa  dla
       %array.

       %array  definiuje yytext jako tablic YYLMAX znakow, co domylnie jest do
       du wartoci. Moesz zmienia rozmiar przez proste #definiowanie YYLMAX  na
       inn  warto  w pierwszej sekcji wejciowego pliku fleksa.  Jak wspomniano
       wyej, dla %pointer  yytext  wzrasta  dynamicznie,  by  przechowywa  due
       tokeny. Chocia oznacza to, e skaner %pointer moe zbiera due tokeny (jak
       np. cale bloki komentarzy), to zakop sobie w pamici, e za  kadym  razem
       gdy  skaner  zmienia rozmiar yytext to musi rownie reskanowa caly token
       od pocztku, wic moe si to okaza powolne.  yytext w chwili  obecnej  nie
       zwiksza dynamicznie rozmiaru jeli wywolanie unput() powoduje wepchnicie
       z powrotem zbyt  duego  bloku  tekstu.  Zamiast  tego  pojawia  si  bld
       wykonania.

       Zauwa te, e postaci %array nie mona uywa z klasami skanerow C++ (zobacz
       opcj c++ poniej).

AKCJE

       Kady wzorzec reguly  ma  odpowiadajc  mu  akcj,  ktora  moe  by  dowoln
       instrukcj  jzyka  C.  Wzorzec  koczy si na pierwszym niecytowanym znaku
       bialej spacji; reszta linijki jest akcj.  Jeli  akcja  jest  pusta,  to
       token  wejciowy  jest  zwyczajnie  odrzucany.  Na przyklad oto program,
       kasujcy wszystkie pojawienia lacucha "wytnij mnie":

           %%
           "wytnij mnie"

       (Wszystkie pozostale znaki wejcia  zostan  skopiowane  na  wyjcie,  gdy
       dopasuj si do reguly domylnej.)

       Oto  program,  ktory  kompresuje  wielokrotne  spacje  i  tabulacje  do
       pojedynczej spacji. Program wycina te wszystkie  biale  spacje  z  koca
       linii:

           %%
           [ \t]+        putchar( ' ' );
           [ \t]+$       /* ignoruj ten token */

       Jeli  akcja  zawiera  znak '{', to rozciga si ona a do zamykajcego '}',
       nawet na przestrzeni wielu linii.  flex ma pewne wiadomoci o  lacuchach
       C i komentarzach, wic nie zostanie oglupione przez klamry, ktore mog si
       w nich znajdowa. Poza tym dozwolone s te akcje, ktore zaczynaj si od %{
       i  zawieraj  tekst  akcji  a do nastpnego %} (niezalenie od zwyczajnych
       klamer wewntrz akcji).

       Akcja skladajca si wylcznie z pionowej kreski ('|') oznacza "taka sama,
       jak akcja nastpnej reguly". Dla zobrazowania patrz niej.

       Akcje  mog  zawiera kod C, wlczajc w to instrukcje return, przeznaczone
       do zwracania wartoci do procedury, ktora wywolala yylex().  Przy  kadym
       wywolaniu yylex() kontynuuje przetwarzanie tokenow od miejsca, w ktorym
       ostatnio przerwal a do osignicia koca pliku lub wywolania return.

       Akcje mog spokojnie modyfikowa zmienn yytext; nie mog jej jednak wydlua
       (dodawanie   znakow  do  jej  koca  nadpisze  dalsze  znaki  strumienia
       wejciowego). Odmiennie jest natomiast przy uywaniu %array (patrz wyej);
       wtedy yytext mona spokojnie modyfikowa w dowolny sposob.

       Podobnie  do  powyszej zmiennej, mona spokojnie modyfikowa yyleng, lecz
       naley uwaa by nie robi tego jeli akcja uywa yymore() (patrz niej).

       Istnieje wiele dyrektyw specjalnych, ktore mona zawrze w akcji:

       -      ECHO kopiuje wejcie yytext na wyjcie skanera.

       -      BEGIN z doklejon nazw warunku  pocztkowego  umieszcza  skaner  w
              odpowiednim warunku pocztkowym (patrz niej).

       -      REJECT  Kieruje  skaner  na  dzialanie  w  "drugiej  najlepszej"
              regule, ktora  zostala  dopasowana  do  wzorca  wejciowego  (lub
              prefiksu wejcia). Regula jest wybierana wedlug zasad opisanych w
              "Jak dopasowywane jest wejcie",  po  czym  nastpuje  odpowiednie
              ustawienie  yytext oraz yyleng.  Moe to by albo ta regula, ktora
              dopasowala si do takiej samej iloci tekstu, jak poprzednia, lecz
              wystpila  poniej  w  pliku  wejciowym  fleksa,  albo taka, ktora
              dopasowala si do mniejszej iloci tekstu.  Na przyklad, nastpujcy
              przyklad  bdzie  liczyl  slowa wejciowe i wolal funkcj special()
              dla kadego "frob":

                          int word_count = 0;
                  %%

                  frob        special(); REJECT;
                  [^ \t\n]+   ++word_count;

              Bez dyrektywy REJECT, slowa "frob" wejcia  nie  bylyby  zliczane
              jako  slowa,  gdy  skaner  normalnie wykonuje tylko jedn akcj na
              token. Dozwolonych jest wiele  komend  REJECT,  z  ktorych  kada
              wyszukuje  najbardziej  pasujcego  nastpc.  Na  przyklad poniszy
              skaner skanujc token "abcd" zapisze na wyjciu "abcdabcaba":

                  %%
                  a        |
                  ab       |
                  abc      |
                  abcd     ECHO; REJECT;
                  .|\n     /* zjedz nietrafione znaki */

              (Pierwsze trzy reguly maj wspoln akcj z czwart, gdy uywaj  akcji
              specjalnej  '|'.)  REJECT jest do kosztown wlaciwoci jeli chodzi
              o wydajno skanera; jeli jest uywane w ktorej z akcji skanera, to
              spowolni wszystkie dopasowania skanera. Co wicej, REJECT nie moe
              by uywany z opcjami -Cf i -CF (zobacz niej).

              Zauwa te, e,  w  przeciwiestwie  do  innych  akcji  specjalnych,
              REJECT jest odga/lzieniem; kod akcji wystpujcy bezporednio po nim
              nie zostanie wykonany.

       -      yymore() mowi skanerowi, e  przy  nastpnym  dopasowaniu  reguly,
              odpowiadajcy  token  powinien  by  doklejony  do  biecej wartoci
              yytext.   Na  przyklad,  przy  wejciu   "mega-kludge",   poniszy
              przyklad na wyjciu wypisze "mega-mega-kludge":

                  %%
                  mega-    ECHO; yymore();
                  kludge   ECHO;

              Pierwsze  "mega-"  jest  dopasowane  i  wydrukowane  na  wyjcie.
              Nastpnie dopasowane jest "kludge", lecz poprzednie  "mega-"  wci
              znajduje  si  na  pocztku  yytext  i  komenda  ECHO dla "kludge"
              wydrukuje w rzeczywistoci "mega-kludge".

       Dwie uwagi na temat yymore().  Po pierwsze, yymore() zaley  od  wartoci
       yyleng,  odzwierciedlajcej  rozmiar  biecego  tokenu. Zatem jeli uywasz
       yymore(), nie modyfikuj tej zmiennej.  Po  drugie,  obecno  yymore()  w
       akcji   skanera  wplywa  na  pewne  pogorszenie  wydajnoci  w  szybkoci
       dokonywania przez skaner dopasowa.

       -      yyless(n) zwraca wszystkie poza  pierwszymi  n  znakami  biecego
              tokenu  z  powrotem  do  strumienia  wejciowego,  skd zostan one
              powtornie przeskanowane  przy  dopasowywaniu  nastpnego  wzorca.
              yytext  i  yyleng  s  odpowiednio  dostrajane (tj.  yyleng bdzie
              teraz rowne n).  Na przyklad, przy  wejciu  "foobar",  nastpujcy
              kod wypisze "foobarbar":

                  %%
                  foobar    ECHO; yyless(3);
                  [a-z]+    ECHO;

              Podanie  yyless  argumentu zerowego powoduje reskanowanie calego
              obecnego  lacucha  wejciowego.  O  ile  nie   zmienisz   sposobu
              kolejnego  przetwarzania  przez  skaner  wejcia  (przy uyciu np.
              BEGIN), spowoduje to nieskoczon ptl.

       Zwro uwag, e  yyless  jest  makrem  i  moe  by  uywane  tylko  z  pliku
       wejciowego fleksa, a nie z innych plikow rodlowych.

       -      unput(c)  wstawia  znak  c  z powrotem do strumienia wejciowego.
              Bdzie to nastpny skanowany znak.  Ponisza akcja  pobierze  biecy
              token i spowoduje, e zostanie reskanowany po ujciu w nawiasy.

                  {
                  int i;
                  /* Kopiuj yytext, gdy unput() niszczy jego zawarto */
                  char *yycopy = strdup( yytext );
                  unput( ')' );
                  for ( i = yyleng - 1; i >= 0; --i )
                      unput( yycopy[i] );
                  unput( '(' );
                  free( yycopy );
                  }

              Zwro  uwag,  e  skoro  kady unput() wstawia dany znak na pocztek
              strumienia, to wstawianie znakow musi odbywa si tylem-na-przod.

       Wanym potencjalnym problemem uywania unput() jest fakt, e  jeli  uywasz
       dyrektywy %pointer (domylne), wywolanie unput() niszczy zawarto yytext,
       poczynajc  od  znaku  najbardziej  z  prawej,  idc  w  lewo  za   kadym
       wywolaniem.   Jeli  potrzebujesz  zachowa  warto  yytext  po  uyciu tej
       funkcji, (jak w powyszym  przykladzie),  musisz  skopiowa  jej  zawarto
       gdzie indziej lub zbudowa skaner z uyciem %array.

       Na  koniec,  zauwa  te, e nie moesz wstawia tak znakow EOF.  Nie mona t
       metod zaznacza koca pliku w strumieniu.

       -      input() odczytuje nastpny  znak  ze  strumienia  wejciowego.  Na
              przyklad,  ponisze  jest  jednym ze sposobow poerania komentarzy
              jzyka C:

                  %%
                  "/*"        {
                              register int c;

                              for ( ; ; )
                                  {
                                  while ( (c = input()) != '*' &&
                                          c != EOF )
                                      ;    /* zeryj tekst komentarza */

                                  if ( c == '*' )
                                      {
                                      while ( (c = input()) == '*' )
                                          ;
                                      if ( c == '/' )
                                          break;    /* znalazlem koniec */
                                      }

                                  if ( c == EOF )
                                      {
                                      error( "EOF w komentarzu" );
                                      break;
                                      }
                                  }
                              }

              (Zauwa, e jeli skaner jest skompilowany z uyciem C++, to input()
              nazywa  si  yyinput().   Jest  tak  w celu zapobieenia zderzeniu
              nazwy ze strumieniem C++ poprzez nazw input.)

       -      YY_FLUSH_BUFFER wypronia wewntrzny bufor skanera. Przy  nastpnym
              razie  gdy  skaner  bdzie  dopasowywal  si  do  tokenu, najpierw
              napelni na nowo bufor z uyciem YY_INPUT (zobacz niej  Generowany
              Skaner).  Akcja ta jest szczegolnym przypadkiem bardziej ogolnej
              funkcji yy_flush_buffer(), opisanej niej  w  sekcji  Wielokrotne
              Bufory Wejciowe.

       -      yyterminate()  moe  by  uywane  zamiast instrukcji return akcji.
              Koczy dzialanie  skanera  i  zwraca  0  do  wywolujcego  skaner,
              wskazujc,  e  "wszystko zrobione".  Domylnie, yyterminate() jest
              wywolywane rownie po napotkaniu koca pliku. Jest to makro i  moe
              by redefiniowane.

GENEROWANY SKANER

       Wynikiem  dzialania  fleksa  jest  plik  lex.yy.c,  zawierajcy procedur
       skanujc  yylex()  oraz  zestaw  tablic,   uywanych   przez   niego   do
       dopasowywania  tokenow  i  par  procedur  i makr. Domylnie yylex() jest
       deklarowany jako

           int yylex()
               {
               ... tu rone definicje i akcje ...
               }

       (Jeli twoje rodowisko obsluguje prototypy funkcji,  to  bdzie  to  "int
       yylex(  void  )".) Definicj t mona zmieni definiujc makro "YY_DECL". Na
       przyklad

           #define YY_DECL float lexscan( a, b ) float a, b;

       informuje fleksa,  by  nada  procedurze  skanujcej  nazw  lexscan  i  e
       procedura  ta  ma  zwraca  typ  float  i pobiera dwa argumenty (te typu
       float). Zwro uwag, e  jeli  podajesz  argumenty  procedurze  skanujcej,
       uywajc  deklaracji  w  niezaprototypowanym  stylu  K&R,  musisz zakoczy
       definicj rednikiem (;).

       Przy kadym wywolaniu yylex(), nastpuje skanowanie tokenow z  globalnego
       pliku  wejciowego  yyin (ktory domylnie wskazuje na stdin). Wczytywanie
       trwa a do osignicia koca pliku, lub a do napotkania w  ktorej  z  akcji
       instrukcji return.

       Jeli skaner osiga koniec pliku, to kolejne wywolania s niezdefiniowane.
       Sposobem na skorygowanie tego jest przekierowanie  yyin  na  nowy  plik
       wejciowy  (w  tym  wypadku  skanowanie  nastpuje  z  nowego  pliku) lub
       wywolanie yyrestart().  yyrestart()  pobiera  jeden  argument:  wskanik
       FILE * (ktory moe by nil, jeli ustawile YY_INPUT na skanowanie ze rodla
       innego ni yyin), i inicjalizuje yyin na pocztek tego pliku. W  zasadzie
       nie  ma ronicy midzy zwyklym przypisaniem yyin do nowego pliku i uyciem
       yyrestart(); Procedura ta  jest  dostpna  z  uwagi  na  kompatybilno  z
       poprzednimi  wersjami  flex,  a  take  dlatego,  e  moe  by  uywana  do
       przelczania plikow wejciowych w rodku skanowania.  Moe by te uywana  do
       porzucania  biecego  bufora  wejciowego  poprzez wywolanie z argumentem
       yyin; lepszym rozwizaniem  jest  jednak  uycie  YY_FLUSH_BUFFER  (patrz
       wyej).   Zauwa,  e  yyrestart()  nie  resetuje  warunku  pocztkowego na
       INITIAL (zobacz niej Warunki Pocztkowe).

       Jeli yylex() koczy skanowanie z powodu wywolania  instrukcji  return  w
       jednej  z  akcji, skaner moe by wolany ponownie i wznowi dzialanie tam,
       gdzie skoczyl.

       Domylnie (i dla celow wydajnoci)  skaner  zamiast  pojedynczych  getc()
       wykonuje  odczyty  blokowe  z  yyin.   Sposob  pobierania wejcia moe by
       kontrolowany przez definiowanie makra  YY_INPUT.   Sekwencja  wywolujca
       YY_INPUT   to  "YY_INPUT(buf,wynik,max_rozmiar)".   Jej  wynikiem  jest
       umieszczenie co najwyej max_rozmiar znakow w  tablicy  znakowej  buf  i
       zwrocenie  w  zmiennej  calkowitej  wynik albo liczby wczytanych znakow
       albo  stalej  YY_NULL  (0  w  systemach  uniksowych),  okrelajcej  EOF.
       Domylnie, YY_INPUT czyta z globalnego wskanika "yyin".

       Przykladowa definicja YY_INPUT (w sekcji definicji pliku wejciowego):

           %{
           #define YY_INPUT(buf,wynik,max_rozmiar) \
               { \
               int c = getchar(); \
               wynik = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
               }
           %}

       Definicja  ta  zmieni  przetwarzanie  wejcia  tak, by naraz pojawial si
       tylko jeden znak.

       W momencie, gdy skaner uzyska od YY_INPUT warunek koca pliku,  to  wola
       funkcj  yywrap().   Jeli  yywrap()  zwroci  zero, to zaklada, e funkcja
       poszla dalej i skonfigurowala yyin  do  wskazywania  na  nowy  plik,  a
       skanowanie  trwa  dalej.  Jeli  zwroci  warto  niezerow,  skaner  koczy
       dzialanie,  zwracajc  0  do  funkcji  wywolujcej.   Zauwa,  e  w  kadym
       przypadku warunek pocztkowy pozostaje niezmieniony; nie przechodzi on w
       INITIAL.

       Jeli nie chcesz podawa wlasnej wersji yywrap(), to musisz albo uy opcji
       %option  noyywrap  (wtedy  skaner zachowuje si, jakby yywrap() zwracalo
       1), albo konsolidowa z -lfl, uzyskujc tak domyln wersj funkcji,  zawsze
       zwracajcej 1.

       Do  skanowania  z  buforow  pamiciowych (a nie z plikow) przeznaczone s
       trzy     procedury:     yy_scan_string(),     yy_scan_bytes()      oraz
       yy_scan_buffer().   Zobacz  niej  dyskusj  w  sekcji Wielokrotne Bufory
       Wejciowe.

       Swoje wyjcie  ECHO  skaner  zapisuje  do  globalnego  strumienia  yyout
       (domylnie  stdout), ktory mona przedefiniowa dziki zwyklemu przypisaniu
       tej zmiennej do innego wskanika FILE.

WARUNKI POCZTKOWE

       flex daje mechanizm warunkowej aktywacji regul. Reguly rozpoczynajce si
       od  "<sc>"  wlcz  si tylko jeli skaner znajduje si w warunku pocztkowym
       "sc". Na przyklad,

           <STRING>[^"]*        { /* zjedz cialo lacucha ... */
                       ...
                       }

       bdzie aktywne tylko jeli skaner jest w warunku pocztkowym "STRING", a

           <INITIAL,STRING,QUOTE>\.        { /* obslu cytowanie ... */
                       ...
                       }

       bdzie  aktywne  tylko  jeli  obecnym  warunkiem  pocztkowym  jest  albo
       "INITIAL", albo "STRING" albo "QUOTE".

       Warunki  pocztkowe  s  deklarowane w sekcji definicji wejcia przy uyciu
       niewcitych linii, zaczynajcych si od %s lub  %x,  za  ktorymi  nastpuje
       lista  nazw.   Pierwsza  posta  deklaruje w/lczajce warunki pocztkowe, a
       druga wykluczajce.  Warunek pocztkowy wlcza si przy uyciu akcji  BEGIN.
       Reguly  uywajce  danego  warunku  pocztkowego bd aktywne a do wywolania
       nastpnej akcji BEGIN.  Jeli warunek pocztkowy jest w/lczajcy , to reguly
       bez  warunkow pocztkowych bd rownie aktywne.  Jeli jest wykluczajcy, to
       wykonywane bd tylko reguly odpowiadajce warunkowi pocztkowemu.   Zestaw
       regul  opierajcych  si  na  tym  samym wykluczajcym warunku pocztkowym,
       opisuje skaner, ktory jest niezaleny od wszelkich innych  regul  wejcia
       fleksa.   Z  uwagi na to, warunki wykluczajce ulatwiaj tworzenie "mini-
       skanerow", ktore skanuj czci wejcia, odmienne syntaktycznie  od  reszty
       (np.  komentarze).

       W  rozronieniu  warunkow  wlczajcych i wykluczajcych istnieje wci pewna
       niejasno: oto przyklad, ilustrujcy ich powizanie. Zestaw regul:

           %s przyklad
           %%

           <przyklad>foo  rob_cos();

           bar            cos_innego();

       jest rownowany

           %x przyklad
           %%

           <przyklad>foo   rob_cos();

           <INITIAL,przyklad>bar    cos_innego();

       Bez  uycia  kwalifikatora  <INITIAL,przyklad>,  wzorzec  bar  w  drugim
       przykladzie  nie  bylby  aktywny  (tj.  nie  dopasowalby  si) w warunku
       pocztkowym  przyklad.   Jeli  uylibymy  do  kwalifikowania  bar   tylko
       <przyklad>,  to byloby aktywny tylko w warunku pocztkowym przyklad, ale
       nie w INITIAL, podczas gdy  w  pierwszym  przykladzie  jest  aktywny  w
       obydwu, gdy warunek pocztkowy przyklad jest w nim w/lczajcy (%s).

       Zauwa  te,  e  specjalny  specyfikator  <*> pasuje do dowolnego warunku
       pocztkowego. Tak wic, powysze mona zapisa rownie nastpujco:

           %x przyklad
           %%

           <przyklad>foo   rob_cos();

           <*>bar    cos_innego();

       Regula  domylna  (wykonywania  ECHO  na  kadym  niedopasowanym   znaku)
       pozostaje aktywna w warunkach pocztkowych.  Jest to w sumie rownowane:

           <*>.|\n     ECHO;

       BEGIN(0)  zwraca do stanu oryginalnego, w ktorym aktywne s tylko reguly
       bez warunku pocztkowego. Stan ten jest oznaczany jako warunek pocztkowy
       "INITIAL",  wic mona go ustawi rownie poprzez BEGIN(INITIAL).  (Nawiasy
       wokol nazwy warunku pocztkowego nie s wymagane, lecz s w dobrym tonie.)

       Akcje BEGIN mog by podawane jako kod wcity na pocztku sekcji regul.  Na
       przyklad, nastpujcy kod spowoduje, e skaner wejdzie w warunek pocztkowy
       "SPECIAL" za kadym razem,  gdy  wywolane  zostanie  yylex()  a  zmienna
       globalna enter_special bdzie ustawiona na prawd:

                   int enter_special;

           %x SPECIAL
           %%
                   if ( enter_special )
                       BEGIN(SPECIAL);

           <SPECIAL>blahblahblah
           ...i kolejne ruguly...

       Dla zilustrowania wykorzystania warunkow pocztkowych, oto skaner, ktory
       daje  dwie  rone  interpretacje  lacucha  "123.456".   Domylnie   bdzie
       traktowal  go  jako  3  elementy,  liczb  calkowit  123,  kropk i liczb
       calkowit "456".  Jeli jednak lacuch zostanie poprzedzony lini z napisem
       "expect-floats",   to   bdzie  go  traktowal  jako  pojedynczy  element
       zmiennoprzecinkowy (123.456).

           %{
           #include <math.h>
           %}
           %s expect

           %%
           expect-floats        BEGIN(expect);

           <expect>[0-9]+"."[0-9]+      {
                       printf( "znalazlem zmiennoprzecinkow, = %f\n",
                               atof( yytext ) );
                       }
           <expect>\n           {
                       /* jest to koniec linii, wic
                        * potrzebujemy kolejnego "expect-number"
                        * przed rozpoznawaniem dalszych liczb
                        */
                       BEGIN(INITIAL);
                       }

           [0-9]+      {
                       printf( "znalazlem calkowit, = %d\n",
                               atoi( yytext ) );
                       }

           "."         printf( "znalazlem kropk\n" );

       Oto skaner, ktory rozpoznaje komentarze C podczas zliczania linii.

           %x comment
           %%
                   int line_num = 1;

           "/*"         BEGIN(comment);

           <comment>[^*\n]*        /* zjedz wszystko, co nie jest '*'     */
           <comment>"*"+[^*/\n]*   /* zjedz '*'-ki, po ktorych nie ma '/' */
           <comment>\n             ++line_num;
           <comment>"*"+"/"        BEGIN(INITIAL);

       Skaner ten moe mie problemy z dopasowaniem maksymalnej iloci  tekstu  w
       kadej   z  regul.  Ogolnie,  przy  pisaniu  szybkich  skanerow,  probuj
       dopasowywa w kadej regule tyle, ile si da.

       Zauwa,  e  nazwy  warunkow  pocztkowych  s   tak   naprawd   wartociami
       calkowitymi  i  mog by tak przechowywane. Tak wic powysze mona rozwin w
       nastpujcym stylu:

           %x comment foo
           %%
                   int line_num = 1;
                   int comment_caller;

           "/*"         {
                        comment_caller = INITIAL;
                        BEGIN(comment);
                        }

           ...

           <foo>"/*"    {
                        comment_caller = foo;
                        BEGIN(comment);
                        }

           <comment>[^*\n]*        /* zjedz wszystko co nie jest '*'   */
           <comment>"*"+[^*/\n]*   /* zjedz '*', po ktorych nie ma '/' */
           <comment>\n             ++line_num;
           <comment>"*"+"/"        BEGIN(comment_caller);

       Co wicej, moesz mie dostp do biecego warunku pocztkowego poprzez  makro
       YY_START  (o  wartoci calkowitej).  Na przyklad, powysze przypisania do
       comment_caller mona by zapisa jako

           comment_caller = YY_START;

       Flex jako alias do YY_START daje YYSTATE (gdy  jest  to  nazwa,  uywana
       przez AT&T lex).

       Zauwa,  e warunki pocztkowe nie maj wlasnej przestrzeni nazw; %s i %x-y
       deklaruj nazwy podobnie jak #define.

       Na deser, oto przyklad dopasowywania cytowanych w stylu C napisow  przy
       uyciu   wykluczajcych   warunkow  pocztkowych,  wlcznie  z  rozwijanymi
       sekwencjami specjalnymi (lecz bez sprawdzania czy lacuch  nie  jest  za
       dlugi):

           %x str

           %%
                   char string_buf[MAX_STR_CONST];
                   char *string_buf_ptr;

           \"      string_buf_ptr = string_buf; BEGIN(str);

           <str>\"        { /* zobaczylem zamykajcy cytat - gotowe */
                   BEGIN(INITIAL);
                   *string_buf_ptr = '\0';
                   /* zwro typ i warto tokenu stalej lacuchowej do
                    * analizatora
                    */
                   }

           <str>\n        {
                   /* bld - niezakoczona stala lacuchowa */
                   /* generuj komunikat o bldzie */
                   }

           <str>\\[0-7]{1,3} {
                   /* osemkowa sekwencja specjalna */
                   int result;

                   (void) sscanf( yytext + 1, "%o", &result );

                   if ( result > 0xff )
                           /* bld, stala poza zakresem */

                   *string_buf_ptr++ = result;
                   }

           <str>\\[0-9]+ {
                   /* generuj bld - zla sekwencja specjalna; co jak
                    * '\48' lub '\0777777'
                    */
                   }

           <str>\\n  *string_buf_ptr++ = '\n';
           <str>\\t  *string_buf_ptr++ = '\t';
           <str>\\r  *string_buf_ptr++ = '\r';
           <str>\\b  *string_buf_ptr++ = '\b';
           <str>\\f  *string_buf_ptr++ = '\f';

           <str>\\(.|\n)  *string_buf_ptr++ = yytext[1];

           <str>[^\\\n\"]+        {
                   char *yptr = yytext;

                   while ( *yptr )
                           *string_buf_ptr++ = *yptr++;
                   }

       Czsto,  np.  w  niektorych  przykladach  powyej  mona skoczy piszc grup
       regul, rozpoczynajcych si od tych  samych  warunkow  pocztkowych.  Flex
       ulatwia  calo  wprowadzajc  pojcie zakresu warunku pocztkowego.  Zakres
       rozpoczyna si od:

           <SCs>{

       gdzie SCs jest list jednego lub  wicej  warunkow  pocztkowych.  Wewntrz
       zakresu   warunku   pocztkowego   kada   regula  dostaje  automatycznie
       przedrostek <SCs> a do napotkania '}', ktory odpowiada startowemu  '{'.
       W ten sposob na przyklad

           <ESC>{
               "\\n"   return '\n';
               "\\r"   return '\r';
               "\\f"   return '\f';
               "\\0"   return '\0';
           }

       jest rownowane:

           <ESC>"\\n"  return '\n';
           <ESC>"\\r"  return '\r';
           <ESC>"\\f"  return '\f';
           <ESC>"\\0"  return '\0';

       Zakresy warunkow pocztkowych mog by zagniedane.

       Do obslugi stosow warunkow pocztkowych s przeznaczone trzy procedury:

       void yy_push_state(int new_state)
              wrzuca  biecy  warunek  pocztkowy na stos warunkow pocztkowych i
              przelcza si w  stan  new_state,  zupelnie  jak  po  uyciu  BEGIN
              new_state  (pamitaj,  e  nazwy  warunkow  pocztkowych  s  rownie
              liczbami calkowitymi).

       void yy_pop_state()
              zdejmuje warto ze stosu i przelcza si na ni przez BEGIN.

       int yy_top_state()
              zwraca wierzcholek stosu bez zmiany zawartoci stosu.

       Stos warunkow pocztkowych ronie dynamicznie i nie ma adnych wbudowanych
       ogranicze. Po wyczerpaniu pamici, wykonywanie programu jest przerywane.

       Aby  korzysta  ze  stosow  warunkow  pocztkowych,  skaner  musi zawiera
       dyrektyw %option stack (zobacz niej rozdzial Opcje).

WIELOKROTNE BUFORY WEJCIOWE

       Niektore skanery (te,  obslugujce  pliki  dolczane  "include")  wymagaj
       odczytu  z  wielu  strumieni  wejciowych.  Poniewa skanery flex wykonuj
       sporo  buforowania,  nie  mona  jednoznacznie   zdecydowa   skd   bdzie
       wykonywany  nastpny  odczyt przez proste napisanie YY_INPUT, ktore jest
       wraliwe na kontekst skanowania.  YY_INPUT  wywolywane  jest  tylko  gdy
       skaner osiga koniec swojego bufora, ktory moe by daleko po wyskanowaniu
       instrukcji takiej jak "include", wymagajcej przelczenia rodla wejcia.

       Aby zalatwi niektore z tych problemow, flex daje mechanizm tworzenia  i
       przelczania  midzy  wielokrotnymi  buforami  wejciowymi. Bufor wejciowy
       jest tworzony z uyciem funkcji

           YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )

       ktora pobiera wskanik FILE i rozmiar  size,  a  nastpnie  tworzy  bufor
       zwizany  z  danym  plikiem,  ktorego  wielko  (w znakach) jest okrelona
       parametrem  rozmiaru.   (w  razie  wtpliwoci   uyj   YY_BUF_SIZE   jako
       rozmiaru).  Funkcja  zwraca  uchwyt YY_BUFFER_STATE, ktory moe by potem
       przekazywany do innych procedur (zobacz niej). Typ YY_BUFFER_STATE jest
       wskanikiem  do  struktury  struct  yy_buffer_state wic mona bezpiecznie
       inicjalizowa zmienne YY_BUFFER_STATE na ((YY_BUFFER_STATE) 0) i  odnosi
       si  do  struktury w celu poprawnego zadeklarowania buforow wejciowych w
       plikach rodlowych innych ni ten od twojego skanera.  Zauwa,  e  wskanik
       FILE  w  wywolaniu  yy_create_buffer  jest uywany tylko jako warto yyin
       widzianego przez YY_INPUT; jeli redefiniujesz  YY_INPUT  tak,  eby  nie
       uywalo  yyin,  to  moesz  spokojnie  przekaza  tu  zerowy wskanik FILE.
       Zadany bufor do skanowania wybiera si za pomoc:

           void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )

       co przelcza bufor wejciowy skanera tak, e kolejne tokeny bd  pochodzily
       z  bufora  new_buffer.   Zauwa,  e  yy_switch_to_buffer() moe by uywane
       przez yywrap() do zestawiania ronych rzeczy  we  wznowionym  skanowaniu
       zamiast  otwierania nowego pliku i ustawiania na nim yyin.  Zauwa te, e
       przelczanie rodel wejciowych przez yy_switch_to_buffer()  lub  yywrap()
       nie zmienia warunku pocztkowego.

           void yy_delete_buffer( YY_BUFFER_STATE buffer )

       uywane  jest  do odzyskania miejsca zwizanego z buforem ( buffer moe by
       wartoci nil, ale wtedy funkcja ta nic nie robi.)  Mona  te  czyci  biec
       zawarto bufora, stosujc:

           void yy_flush_buffer( YY_BUFFER_STATE buffer )

       Funkcja ta niszczy zawarto bufora, wic przy nastpnej probie dopasowania
       tokenu z bufora, skaner najpierw wypelni bufor na nowo uywajc YY_INPUT.

       yy_new_buffer() jest  synonimem  yy_create_buffer(),  udostpnionym  dla
       zgodnoci  z  C++  narzdziami  new  i  delete,  slucymi  do  tworzenia i
       niszczenia obiektow dynamicznych.

       Na koniec makro  YY_CURRENT_BUFFER  zwraca  uchwyt  YY_BUFFER_STATE  do
       biecego bufora.

       A  oto  przyklad  uywania  tych wlaciwoci w skanerze, rozwijajcym pliki
       zalczane (wlaciwo <<EOF>> jest opisywana niej):

           /* stan "incl" jest uywany do wybierania nazwy zalczanego pliku
            */
           %x incl

           %{
           #define MAX_INCLUDE_DEPTH 10
           YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
           int include_stack_ptr = 0;
           %}

           %%
           include             BEGIN(incl);

           [a-z]+              ECHO;
           [^a-z\n]*\n?        ECHO;

           <incl>[ \t]*      /* zjedz bial spacj */
           <incl>[^ \t\n]+   { /* mam nazw pliku zalcznika */
                   if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
                       {
                       fprintf( stderr, "Zbyt zagniedone zalczniki" );
                       exit( 1 );
                       }

                   include_stack[include_stack_ptr++] =
                       YY_CURRENT_BUFFER;

                   yyin = fopen( yytext, "r" );

                   if ( ! yyin )
                       error( ... );

                   yy_switch_to_buffer(
                       yy_create_buffer( yyin, YY_BUF_SIZE ) );

                   BEGIN(INITIAL);
                   }

           <<EOF>> {
                   if ( --include_stack_ptr < 0 )
                       {
                       yyterminate();
                       }

                   else
                       {
                       yy_delete_buffer( YY_CURRENT_BUFFER );
                       yy_switch_to_buffer(
                            include_stack[include_stack_ptr] );
                       }
                   }

       Do zestawiania buforow wejciowych  dla  skanowania  lacuchow  z  pamici
       zamiast  plikow  istniej  trzy procedury. Kada z nich tworzy nowy bufor
       wejciowy  do  skanowania   lacucha   i   zwraca   odpowiadajcy   uchwyt
       YY_BUFFER_STATE  (ktory powiniene skasowa stosujc yy_delete_buffer() po
       zakoczeniu dzialania). Przelczaj one te  przetwarzanie  na  nowy  bufor
       przy   uyciu   yy_switch_to_buffer(),  wic  nastpne  wywolanie  yylex()
       rozpocznie skanowanie lacucha.

       yy_scan_string(const char *str)
              skanuje lacuch zakoczony zerem.

       yy_scan_bytes(const char *bytes, int len)
              skanuje len bajtow  (dopuszczalne  zera  w  rodku)  poczwszy  od
              pozycji bytes.

       Zauwa,  e  obydwie  funkcje  tworz  i skanuj kopie oryginalnych danych.
       (Jest to podane, gdy yylex() modyfikuje  zawarto  skanowanego  bufora.)
       Kopiowania mona unikn, stosujc:

       yy_scan_buffer(char *base, yy_size_t size)
              ktore  skanuje  bufor na miejscu, zaczynajc od base, a w dlugoci
              size   bajtow,   z   ktorych   dwa   bajty   musz   by   znakami
              YY_END_OF_BUFFER_CHAR  (ASCII  NUL).   Ostatnie  dwa bajty nie s
              skanowane;  tak  wic  skanowanie   przebiega   od   base[0]   do
              base[size-2] wlcznie.

              Jeli  nie  ustawisz  odpowiednio base to yy_scan_buffer() zwraca
              wskanik nil zamiast tworzy nowy bufor wejciowy.

              Typ  yy_size_t  jest  typem  calkowitym,  na  ktory  rzutuje  si
              wyraenie calkowite, okrelajce rozmiar bufora.

REGU/LY END-OF-FILE

       Specjalna   regula  "<<EOF>>"  okrela  akcje,  ktore  naley  wykona  po
       osigniciu koca pliku i gdy yywrap()  zwraca  zero  (tj.  wskazuje  brak
       dalszych  plikow  do  przetworzenia).  Akcja musi si zakoczy zrobieniem
       jednej z czterech rzeczy:

       -      przypisaniem yyin do  nowego  pliku  wejciowego  (w  poprzednich
              wersjach fleksa po dokonaniu przypisania nalealo wywola specjaln
              akcj YY_NEW_FILE; nie jest to ju wymagane);

       -      wywolaniem instrukcji return;

       -      wywolaniem specjalnej akcji yyterminate();

       -      przelczeniem na nowy bufor za pomoc yy_switch_to_buffer().

       Reguly <<EOF>> nie  mog  by  uywane  z  innymi  wzorcami;  mog  one  by
       kwalifikowane  jedynie  list  warunkow  pocztkowych.  Jeli  podana jest
       niekwalifikowana regula <<EOF>>, to  dotyczy  ona  wszystkich  warunkow
       pocztkowych,  ktore  nie  maj  jeszcze  akcji  <<EOF>>.  Aby poda regul
       <<EOF>> tylko dla pocztkowego warunku pocztkowego uyj

           <INITIAL><<EOF>>

       Te reguly przydatne s do lapania rzeczy takich, jak niezamknite cytaty.
       Przyklad:

           %x quote
           %%

           ...inne reguly cytatowe...

           <quote><<EOF>>   {
                    error( "nie zamknity cytat" );
                    yyterminate();
                    }
           <<EOF>>  {
                    if ( *++filelist )
                        yyin = fopen( *filelist, "r" );
                    else
                       yyterminate();
                    }

R'ONE MAKRA

       Mona  zdefiniowa  makro  YY_USER_ACTION,  ktore  sluy  do podania akcji
       wykonywanej zawsze przed akcj dopasowanej reguly. Na  przyklad  moe  by
       #definiowane  do  wywolywania  procedury  konwertujcej  yytext  na male
       litery.  Gdy wywolywane  jest  YY_USER_ACTION,  zmienna  yy_act  okrela
       numer  dopasowanej  reguly (reguly s numerowane od 1). Zalomy, e chcesz
       wyprofilowa jak czsto  jest  uywana  kada  z  regul.  Rozwizaniem  jest
       nastpujcy kawalek kodu:

           #define YY_USER_ACTION ++ctr[yy_act]

       gdzie  ctr jest tablic przechowujc zawarto ronych regul. Zauwa, e makro
       YY_NUM_RULES daje ogoln liczb regul (lcznie z regul domyln, nawet  jeli
       uywasz -s), wic poprawn deklaracj ctr jest:

           int ctr[YY_NUM_RULES];

       Makro YY_USER_INIT sluy do podania akcji, ktora bdzie wykonywana zawsze
       przed pierwszym skanem (i przed wewntrznymi  inicjalizacjami  skanera).
       Na  przyklad  mona to wykorzysta do wolania procedury czytajcej tablice
       danych lub otwierajcej plik raportowy.

       Makro yy_set_interactive(is_interactive) moe by  uywane  do  sterowania
       czy  biecy  bufor jest uwaany za interaktywny.  Bufor interaktywny jest
       przetwarzany wolniej, lecz musi by uywany gdy wejcie  rzeczywicie  jest
       interaktywne.   Zapobiega  to  problemom  zwizanym  z  oczekiwaniem  na
       wypelnienie buforow (zobacz niej dyskusj flagi -I).  Warto niezerowa  w
       wywolaniu  makra  zaznacza  bufor  jako interaktywny, a zero to wylcza.
       Zauwa, e uycie tego  makra  przeslania  %option  always-interactiv  lub
       %option  never-interactive  (zobacz  niej  Opcje).   Przed  rozpoczciem
       skanowania bufora, ktory jest (lub nie jest) interaktywny, naley wywola
       funkcj yy_set_interactive().

       Makro  yy_set_bol(at_bol) moe by wykorzystywane do sterowania czy biecy
       kontekst  skanujcy  bufora  dla  nastpnego  dopasowania   tokena   jest
       dokonywany  jak  gdyby  od  pocztku  linii.  Niezerowa  warto argumentu
       powoduje, e reguly zakotwiczone w '^' staj si aktywne, a  warto  zerowa
       je dezaktywuje.

       Makro  YY_AT_BOL()  zwraca prawd jeli nastpny token skanowany z biecego
       bufora bdzie mial aktywne  reguly  '^'.  W  przeciwnym  wypadku  zwraca
       falsz.

       W  niektorych  generowanych  skanerach akcje s zebrane wszystkie w jedn
       wielk instrukcj switch i s  rozdzielone  makrem  YY_BREAK,  ktore  mona
       redefiniowa.  Domylnie  jest  to  po  prostu  "break".   Redefiniowanie
       YY_BREAK umoliwia uytkownikom C++ zadeklarowanie, by makro  nie  robilo
       niczego  (uwaajc  przy  tym  szczegolnie,  by  kada  regula  koczyla si
       instrukcj  "break"  lub  "return"!).  Mona  tak  zapobiec   cierpieniom
       spowodowanym  ostrzeeniami  o  tym,  e  przez  zakoczenie  akcji reguly
       instrukcj return, YY_BREAK jest nieosigalne.

WARTOCI DOSTPNE DLA UYTKOWNIKA

       Sekcja ta zestawia  rone  wartoci  dostpne  dla  uytkownika  w  akcjach
       regulowych.

       -      char  *yytext  zawiera  biecy tekst tokenu. Moe by modyfikowany,
              lecz nie moe by wydluany (nie mona dokleja dodatkowych znakow na
              kocu).

              Jeli  w  pierwszej  sekcji  opisu  skanera  pojawi  si dyrektywa
              specjalna  %array  to   yytext   zostanie   zadeklarowane   jako
              charyytext[YYLMAX],  gdzie  YYLMAX jest makrodefinicj, ktor mona
              przedefiniowa w pierwszej sekcji (warto domylna to ogolnie 8KB).
              Uywanie  %array daje wolniejsze skanery, lecz warto yytext staje
              si odporna na wywolania input() i  unput(),  ktore  potencjalnie
              niszcz   jego  warto  kiedy  yytext  jest  wskanikiem  znakowym.
              Przeciwn dyrektyw do %array jest %pointer, ktora  jest  dyrektyw
              domyln.

              Dyrektywy  %array  nie mona uywa do generowania klas skanera C++
              (flaga -+).

       -      int yyleng przechowuje dlugo biecego tokenu.

       -      FILE *yyin jest  plikiem,  z  ktorego  flex  domylnie  odczytuje
              wejcie. Moe by redefiniowany, lecz taki zabieg ma sens tylko nim
              rozpocznie si skanowanie lub po napotkaniu EOF.  Zmienianie  tej
              wartoci  w  rodku  skanowania  moe  da  nieoczekiwane  rezultaty
              spowodowane  buforowaniem  wejcia.  Zamiast   tego   uyj   wtedy
              yyrestart().   Po  zakoczeniu  skanowania  przez napotkanie koca
              pliku, mona przypisa warto yyin do  nowego  pliku  wejciowego  i
              wywola ponownie skaner by dokoczyl skanowanie.

       -      void  yyrestart(  FILE  *new_file ) moe by wolane do wskazywania
              yyin na nowy  plik  wejciowy.  Przelczenie  na  nowy  plik  jest
              natychmiastowe   (wszelkie  poprzednio  buforowane  wejcie  jest
              tracone). Zauwa, e wolanie yyrestart() z argumentem yyin porzuca
              biecy  bufor  wejciowy i kontynuuje skanowanie tego samego pliku
              wejciowego.

       -      FILE *yyout jest plikiem, do ktorego kierowane jest wyjcie akcji
              ECHO.  Uytkownik moe mu przypisa inn warto.

       -      YY_CURRENT_BUFFER   zwraca  uchwyt  YY_BUFFER_STATE  do  biecego
              bufora.

       -      YY_START zwraca warto calkowit,  odpowiadajc  biecemu  warunkowi
              pocztkowemu.   Wartoci tej mona uywa dalej z BEGIN do powrotu do
              tego warunku.

/LCZENIE Z YACC

       Jednym  z  podstawowych  zastosowa   fleksa   jest   wspoltowarzyszenie
       generatorowi  analizatorow  yacc.   Analizatory  skladni  yacc  oczekuj
       wywolania procedury o nazwie yylex() celem znalezienia kolejnego tokenu
       wejciowego.  Procedura  powinna zwroci typ nastpnego tokenu oraz wstawi
       zwizan z nim warto do globalnej zmiennej yylval.   Aby  uywa  fleksa  z
       yaccem,  naley  yaccowi  przekaza   opcj  -d,  co  kae mu generowa plik
       y.tab.h zawierajcy definicje wszystkich %token'ow(%tokens)  pojawiajcych
       si  w  wejciu  yacc.   Plik  ten  jest  nastpnie  zalczany  do  skanera
       fleksowego.  Na przyklad jeli jednym z tokenow jest "TOK_NUMBER", to cz
       skanera moe wyglda tak:

           %{
           #include "y.tab.h"
           %}

           %%

           [0-9]+        yylval = atoi( yytext ); return TOK_NUMBER;

OPCJE

       flex ma nastpujce opcje:

       -b     Generuje  informacje  zapasowe  do lex.backup.  Oto lista stanow
              skanera, ktore wymagaj kopii zapasowych oraz znaki wejciowe  dla
              ktorych  to  zachodzi.  Dodajc  reguly mona usun stany zapasowe.
              Jeli wyeliminowane zostan wszystkie stany zapasowe, a uyte bdzie
              -Cf  lub -CF, wygenerowany skaner bdzie dzialal szybciej (zobacz
              flag  -p).   Opcj  to  powinni  si  martwi  jedynie   uytkownicy
              wyciskajcy  ostatnie  poty  ze  swoich skanerow. (Zobacz sekcj o
              Rozwaaniach nad Wydajnoci.)

       -c     nieuywana i niezalecana opcja dla zgodnoci z POSIX-em.

       -d     powoduje, e generowany skaner dziala w trybie debug.   Za  kadym
              razem  po rozpoznaniu wzorca, gdy globalna zmienna yy_flex_debug
              jest niezerowa (co jest domylne), skaner zapisze na stderr  lini
              w postaci:

                  --accepting rule at line 53 ("dopasowany tekst")

              Numer  linii  odnosi  si  do poloenia reguly w pliku definiujcym
              skaner (tj.   w  pliku,  potraktowanym  fleksem).  Komunikaty  s
              rownie  generowane  gdy  skaner  robi  kopie zapasowe, przyjmuje
              domyln regul, dochodzi do koca bufora (lub napotyka NUL;  w  tym
              momencie  obydwa [zdarzenia] wygldaj jednakowo z punktu widzenia
              skanera) lub osiga koniec pliku.

       -f     okrela szybki skaner.  Nie dokonywana  jest  kompresja  tabel  i
              pomijane  jest stdio. W efekcie kod jest duy, lecz szybki. Opcja
              ta jest rownowana -Cfr (zobacz niej).

       -h     generuje zestawienie "pomocy" opcji fleksa  na  stdout  i  koczy
              dzialanie.  -?  i --help s rownowanikami -h.

       -i     nakazuje  fleksowi  generowania  skanera  niewraliwego na wielko
              znakow.  Wielko liter we wzorcach zostanie zignorowany, a tokeny
              wejcia  bd dopasowywane niezalenie od wielkoci. Dopasowany tekst
              znajdujcy si w  yytext  bdzie  mial  zachowan  oryginaln  wielko
              liter.

       -l     wlcza  maksymaln  zgodno  z oryginaln implementacj leksa z AT&T.
              Zauwa, e  nie  oznacza  to  pelnej  zgodnoci.  Uycie  tej  opcji
              kosztuje  sporo wydajnoci i eliminuje z uycia opcje -+,-f,-F,-Cf
              lub -CF.  Dla szczegolow o  zapewnianej  zgodnoci,  zobacz  niej
              sekcj  o  niezgodnociach  midzy  Leksem  i  POSIX-em.  Opcja  ta
              powoduje   te   z#definiowanie   nazwy   YY_FLEX_LEX_COMPAT    w
              generowanym skanerze.

       -n     kolejna ignorowana opcja dodana dla zgodnoci z POSIX-em.

       -p     generuje  raport  o  wydajnoci  na  stderr.  Raport  sklada si z
              komentarzy o wlaciwociach pliku wejciowego fleksa, wic  powoduje
              znaczn  utrat  wydajnoci skanera. Jeli podasz t flag dwukrotnie,
              uzyskasz te komentarze o  wlaciwociach,  ktore  doprowadzily  do
              drugorzdnych utrat wydajnoci.

              Zauwa,  e  uycie  REJECT, %option yylineno, i zmiennego wiszcego
              kontekstu (variable trailing  context)  (zobacz   niej  sekcj  o
              Niedostatkach / Bldach) powoduje znaczn utrat wydajnoci; uywanie
              yymore(), operatora ^ i  flagi  -I  powoduje  pomniejsze  utraty
              wydajnoci.

       -s     powoduje,  e  domylna  regula  (powodujca  echo  niedopasowanego
              wejcia skanera na  stdout)  nie  jest  wykonywana.  Jeli  skaner
              napotka  wejcie,  ktorego  nie  moe  dopasowa do regul, przerywa
              dzialanie z bldem. Opcja ta jest przydatna do znajdowania  dziur
              w zbiorze regul skanera.

       -t     nakazuje    fleksowi   zapisanie   wygenerowanego   skanera   na
              standardowe wyjcie zamiast do pliku lex.yy.c.

       -v     nakazuje  fleksowi  pisanie  na  stderr  zestawienia   statystyk
              dotyczcych   generowanego   skanera.    Wikszo   statystyk  jest
              pozbawiona znaczenia dla typowego uytkownika,  lecz  pierwsza  z
              linijek  wskazuje  wersj fleksa (to samo co zglasza opcja -V), a
              nastpna linia flagi uyte do  generowania  skanera,  z  domylnymi
              wlcznie.

       -w     powstrzymuje komunikaty o ostrzeeniach.

       -B     nakazuje  fleksowi generowanie skanera wsadowego, czyli odwrotno
              skanerow interaktywnych, generowanych przez  -I  (zobacz  niej).
              Ogolnie,  opcji  -B uywa si majc pewno, e skaner nigdy nie bdzie
              uywany interaktywnie  i  chcc  wycisn  jeszcze  troszeczk  wicej
              wydajnoci. Jeli chcesz zyska wicej wydajnoci, powiniene uy opcji
              -Cf  lub  -CF  (opisanych  niej),  ktore   wlczaj   -B   i   tak
              automatycznie.

       -F     mowi,  e  naley  uy  reprezentacji  tablicy szybkiego skanera (i
              stdio ma by pominite). Reprezentacja ta  jest  mniej  wicej  tak
              szybka  jak  reprezentacja pelnej tablicy (-f), i dla niektorych
              zestawow wzorcow bdzie znacznie mniejsza (a dla innych  wiksza).
              Ogolnie,  jeli  wzorzec  zawiera  zarowno "slowa kluczowe" jak i
              lapic-wszystko regul "identyfikatora", tak jak poniszy zestaw:

                  "case"    return TOK_CASE;
                  "switch"  return TOK_SWITCH;
                  ...
                  "default" return TOK_DEFAULT;
                  [a-z]+    return TOK_ID;

              to lepiej uy reprezentacji  pelnej  tablicy.  Jeli  obecna  jest
              tylko  regula "identyfikatora" i uywasz potem hasza lub podobnej
              rzeczy do wykrywania slow kluczowych, to lepiej uy opcji -F.

              Opcja ta odpowiada -CFr (zobacz niej).  Nie mona jej uywa z -+.

       -I     nakazuje fleksowi generowanie  skanera  interaktywnego.   Skaner
              interaktywny  patrzy  naprzod do wyboru dopasowania jedynie jeli
              musi.  Okazuje si, e patrzenie o  jeden  dodatkowy  znak  dalej,
              nawet  jeli  skaner  ma  ju  do do dopasowania tokenu jest troch
              szybsze ni wersja minimalna.  Lecz skanery patrzce  naprzod  daj
              dziadowsk  wydajno interaktywn; na przyklad gdy uytkownik wpisze
              now lini, to nie jest ona rozpoznawana jako  token  nowej  linii
              dopoki  nie wprowadzony zostanie nastpny token, co oznacza czsto
              wpisanie calej kolejnej linii.

              Skanery fleksa s domylnie interaktywne,  chyba  e  uyjesz  opcji
              kompresji  tablicy -Cf lub -CF (zobacz niej).  Jest tak dlatego,
              e jeli oczekujesz wysokiej wydajnoci, to powiniene uy  jednej  z
              tych opcji, a jeli tego nie zrobile, flex zaklada, e jeste gotow
              powici  troch  wydajnoci  na   rzecz   intuicyjnego   zachowania
              interaktywnego.  Zauwa  te,  e nie moesz uy -I w polczeniu z -Cf
              lub -CF.  Z tej przyczyny opcja  ta  nie  jest  w  rzeczywistoci
              wymagana; jest domylnie wlczona dla tych przypadkow, dla ktorych
              jest dopuszczalna.

              Opcj -B moesz wymusi by  skaner  nie  byl  interaktywny  (zobacz
              powyej).

       -L     nakazuje  fleksowi  nie  generowa dyrektyw #line.  Bez tej opcji
              flex  przyprawia  generowany  skaner  dyrektywami   #line,   wic
              komunikaty  o  bldach  w  akcjach  bd  poprawnie poloone wzgldem
              oryginalnego pliku wejciowego fleksa (jeli bldy wynikaj z kodu w
              pliku  wejciowym) lub [wzgldem] lex.yy.c (jeli bldy s win fleksa
              -- powiniene zglosi takie bldy pod adres e-mail podany poniej.)

       -T     powoduje, e flex dziala w trybie ledzenia.  Bdzie  generowal  na
              stderr  wiele  komunikatow  o  postaci  wejcia  i wynikajcych ze
              niedeterministycznych    i     deterministycznych     automatach
              skoczonych. Opcja ta jest uywana zwykle w opiece nad fleksem.

       -V     drukuje  numer  wersji  na  stdout i koczy dzialanie.  --version
              jest synonimem -V.

       -7     nakazuje fleksowi generowanie skanera  7-bitowego,  tj.  takiego
              ktory  moe rozpoznawa w swoim wejciu tylko znaki 7-bitowe. Zalet
              uywania -7 jest to, e tablice skanera bd  o  polow  mniejsze  ni
              wygenerowane opcj -8 (zobacz niej). Wad jest to, e skanery takie
              czsto si zawieszaj lub zalamuj jeli na ich  wejciu  znajdzie  si
              znak 8-bitowy.

              Zauwa  jednak, e jeli generujesz skaner z uyciem opcji kompresji
              tablic -Cf lub  -CF,  to  uycie  -7  zachowa  jedynie  niewielki
              rozmiar  przestrzeni tablic, a spowoduje, e skaner bdzie znaczco
              mniej przenony.  Domylnym zachowaniem  fleksa  jest  generowanie
              skanerow  8-bitowych,  chyba  e  uyto opcji -Cf lub -CF, i wtedy
              flex generuje domylnie skaner 7-bitowy, chyba  e  twoja  maszyna
              zawsze  byla  skonfigurowana  na generowanie skanerow 8-bitowych
              (co czsto si zdarza poza USA). To, czy flex wygenerowal skaner 7
              czy  8 bitowy, mona okreli, sprawdzajc zestawienie flag w wyjciu
              -v, co opisano wyej.

              Zauwa, e jeli uywasz -Cfe lub -CFe, flex wci  domylnie  generuje
              skaner  8-bitowy,  gdy po kompresji pelne tablice 8-bitowe nie s
              wiele wiksze od 7-bitowych.

       -8     nakazuje fleksowi generowanie skanera 8-bitowego,  tj.  takiego,
              ktory  rozpoznaje znaki 8-bitowe. Flaga ta jest wymagana jedynie
              dla skanerow wygenerowanych z uyciem -Cf lub -CF, gdy  w  innych
              wypadkach jest ona przyjmowana jako domylna.

       -+     okrela, e chcesz by fleks wygenerowal klas skanera w C++. Zobacz
              sekcj o generowaniu skanerow C++.

       -C[aefFmr]
              steruje poziomem kompresji  tablic,  balansujc  midzy  malymi  a
              szybkimi skanerami.

              -Ca  ("wyrownaj")  nakazuje  fleksowi  powici  rozmiar  tablic w
              wygenerowanych skanerach na rzecz szybkoci, gdy elementy  tablic
              mog  by lepiej wyrownane pod ktem dostpu do pamici i oblicze. Na
              niektorych  architekturach  RISC  pobieranie  i  operowanie   na
              dlugich   slowach   jest   efektywniejsze   ni   na   mniejszych
              jednostkach, takich jak  krotkie  slowa.  Opcja  ta  moe  podwoi
              rozmiar tablic uywanych przez twoj skaner.

              -Ce  Nakazuje  fleksowi budowanie klas r'ownowanoci, tj. zestawow
              znakow  o  identycznych  wlaciwociach  leksykalnych  (np.   jeli
              jedynym  wystpieniem  cyfr  w  pliku wejciowym fleksa jest klasa
              znakow "[0-9]", to cyfry z przedzialy od 0 do 9 zostan wstawione
              do  tej  samej  klasy  rownowanoci.  Klasy takie zwykle znacznie
              redukuj ostateczne rozmiary tablic/obiektow (zwykle 2-5 razy)  i
              s  calkiem  tanie  od  strony wydajnociowej (jedno podgldnicie w
              tablicy na skanowany znak).

              -Cf okrela, e naley generowa pe/lne tablice skanera - flex nie ma
              ich  kompresowa poprzez branie korzyci z podobnych funkcji przej
              dla ronych stanow.

              -CF okrela, e naley  uy  alternatywnej,  szybkiej  reprezentacji
              skanera  (opisanej  pod  flag -F).  Opcja ta nie moe by uywana z
              -+.

              -Cm nakazuje fleksowi budowanie klas meta-r'ownowanoci,  ktore  s
              zbiorami  klas  rownowanoci  (lub znakow, jeli klasy rownowanoci
              nie s uywane), ktore s czsto  uywane  wspolnie.  Klasy  takie  s
              czsto  dobr  rzecz  podczas uywania skompresowanych tablic, lecz
              maj one ju umiarkowany wplyw na wydajno (dwa lub jeden test "if"
              i jedno podgldnicie tablicy na skanowany znak).

              -Cr  powoduje,  e  generowany  skaner  omija  uycie standardowej
              biblioteki I/O dla wejcia.  Zamiast  wola  fread()  lub  getc(),
              skaner  bdzie  uywa  wywolania  systemowego  read(), zyskujc tak
              troch na wydajnoci (w skali zalenej od systemu). W rzeczywistoci
              jest   to  bez  znaczenia,  chyba  e  uywasz  te  -Cf  lub  -CF.
              Wykorzystanie -Cr moe te spowodowa dziwne  zachowanie  jeli  np.
              odczytasz  z yyin z pomoc stdio przed wywolaniem skanera (skaner
              pominie  tekst  pozostawiony  przez  twoje  odczyty  w   buforze
              wejciowym stdio).

              -Cr   nie   dziala   jeli  zdefiniujesz  YY_INPUT  (zobacz  wyej
              Generowany Skaner).

              Samotne -C okrela, e tablice skanera  powinny  by  kompresowane,
              lecz nie naley uywa klas rownowanoci i klas metarownowanoci.

              Opcje  -Cf  lub  -CF i -Cm nie maj sensu razem - nie ma sytuacji
              dla klas metarownowanoci jeli  tablica  nie  jest  kompresowana.
              Poza tym opcje mona swobodnie lczy.

              Domylnym  ustawieniem  jest  -Cem, ktore okrela, e flex powinien
              generowa klasy rownowanoci i metarownowanoci. Ustawienie to daje
              najwyszy  stopie  kompresji tablic. Kosztem wikszych tablic mona
              uzyska szybciej wykonujce si skanery. Nastpujce zestawienie jest
              mniej wicej prawdziwe:

                  najwolniejsze i najmniejsze
                        -Cem
                        -Cm
                        -Ce
                        -C
                        -C{f,F}e
                        -C{f,F}
                        -C{f,F}a
                  najszybsze i najwiksze

              Zauwa,  e skanery z najmniejszymi tablicami s zwykle najszybciej
              generowane  i  kompilowane,   wic   podczas   prac   rozwojowych
              prawdopodobnie    najchtniej    uyjesz   domylnej,   maksymalnej
              kompresji.

              -Cfe jest czsto dobrym kompromisem midzy  szybkoci  a  rozmiarem
              dla skanerow gotowych do wdroenia (production scanners).

       -ooutput
              nakazuje  fleksowi  zapisanie skanera do pliku output zamiast do
              lex.yy.c.  Jeli polczysz -o z opcj -t, to skaner jest zapisywany
              na  stdout,  lecz  jego  dyrektywy  #line (zobacz wyej opcj -L),
              odnosz si do pliku output.

       -Pprefiks
              zmienia  domylny  przedrostek  yy  uywany   przez   fleksa   dla
              wszystkich  zmiennych  i  funkcji  globalnych  na  prefiks.   Na
              przyklad -Pfoo zmienia nazw yytext na footext.   Zmienia  to  te
              nazw  domylnego pliku wyjciowego z lex.yy.c na lex.foo.c.  A oto
              wszystkie nazwy, ktorych dotyczy takie zachowanie:

                  yy_create_buffer
                  yy_delete_buffer
                  yy_flex_debug
                  yy_init_buffer
                  yy_flush_buffer
                  yy_load_buffer_state
                  yy_switch_to_buffer
                  yyin
                  yyleng
                  yylex
                  yylineno
                  yyout
                  yyrestart
                  yytext
                  yywrap

              (Jeli uywasz skanera C++, to dotyczy to  bdzie  tylko  yywrap  i
              yyFlexLexer.)   Wewntrz  samego  skanera  mona wci uywa jednej i
              drugiej konwencji nazywania; jednak z zewntrz dozwolone s  tylko
              nazwy zmodyfikowane.

              Opcja ta umoliwia latwe lczenie w calo ronych programow fleksa w
              jeden plik  wykonywalny.  Zauwa  jednak,  e  uywanie  tej  opcji
              zmienia  te  nazw yywrap(), wic musisz teraz albo udostpni wlasn
              wersj  tej  procedury  dla  swojego  skanera,  albo  uy  %option
              noyywrap, gdy konsolidacja z -lfl nie daje ju funkcji domylnej.

       -Sskeleton_file
              przeslania  domylny  plik szkieletowy, na podstawie ktorego flex
              buduje swoje skanery.  Nie  bdziesz  uywa  tej  opcji,  chyba  e
              zajmujesz si rozwojem fleksa.

       flex  daje  te  mechanizm  kontrolowania  opcji  z  samej  specyfikacji
       skanera, zamiast  linii  polece.  Dziala  to  przez  wlczanie  dyrektyw
       %option  w  pierwszej  sekcji specyfikacji skanera. W jednej dyrektywie
       %option mona podawa wiele opcji,  a  w  samej  pierwszej  sekcji  pliku
       wejciowego fleksa mona uywa wielu dyrektyw.

       Wikszo   opcji   jest   podawana  po  prostu  jako  nazwy,  poprzedzone
       opcjonalnie slowem "no" (bez bialych spacji w rodku), ktore neguje  ich
       znaczenie.  Cz jest rownowana flagom fleksa lub ich negacjom:

           7bit            -7
           8bit            -8
           align           -Ca
           backup          -b
           batch           -B
           c++             -+

           caseful lub
           case-sensitive  przeciwne do -i (domylne)

           case-insensitive lub
           caseless        -i

           debug           -d
           default         przeciwne do -s
           ecs             -Ce
           fast            -F
           full            -f
           interactive     -I
           lex-compat      -l
           meta-ecs        -Cm
           perf-report     -p
           read            -Cr
           stdout          -t
           verbose         -v
           warn            przeciwne do -w
                           (dla -w uyj "%option nowarn")

           array           rownowane "%array"
           pointer         rownowane "%pointer" (domylne)

       Niektore %opcje daj wlaciwoci niedostpne gdzie indziej:

       always-interactive
              nakazuje  fleksowi  generowanie skanera, ktory zawsze uwaa swoje
              wejcie za "interaktywne". Normalnie przy kadym  pliku  wejciowym
              skaner  wola  isatty()  do  okrelenia  czy  wejcie  skanera jest
              interaktywne i powinno by czytane po znaku. Po uyciu  tej  opcji
              wywolanie takie nie jest robione.

       main   nakazuje  fleksowi  udostpni domylny program main() dla skanera,
              ktory po prostu  wola  yylex().   Opcja  ta  implikuje  noyywrap
              (zobacz niej).

       never-interactive
              nakazuje  fleksowi  generowanie skanera, ktory zawsze uwaa swoje
              wejcie za "nieinteraktywne" (znow, nie  jest  wolane  isatty()).
              Opcja ta jest przeciwna do always-interactive.

       stack  wlcza  uywanie  stosow warunkow pocztkowych (zobacz wyej Warunki
              Pocztkowe).

       stdinit
              jeli  jest  ustawione  (np.   %option   stdinit)   to   zachodzi
              inicjalizacja  yyin i yyout na stdin i stdout, zamiast domylnych
              nil.  Niektore istniejce programy lex zale od  tego  zachowania,
              nawet  jeli  nie  jest  ono  zgodne  z ANSI C, ktore nie wymagaj
              stalych czasu kompilacji stdin i stdout.

       yylineno
              nakazuje fleksowi generowanie skanera, ktory  przechowuje  liczb
              obecnie  odczytanych linii w zmiennej globalnej yylineno.  Opcja
              ta jest wymuszana przez %option lex-compat.

       yywrap jeli nie jest ustawione (np.  %option noyywrap), to  skaner  nie
              wola  yywrap() na kocu pliku, lecz po prostu przyjmuje, e nie ma
              ju plikow do skanowania (dopoki uytkownik nie wskae yyin na nowy
              plik i nie wywola yylex() ponownie).

       flex  skanuje  akcje regul w celu okrelenia czy uywasz wlaciwoci REJECT
       lub yymore().  Opcje reject i yymore mog przesloni jego decyzj na  tak,
       jak  ustawisz  przy  uyciu  opcji,  zarowno  ustawiajc je (np.  %option
       reject) do wskazania, e wlaciwo jest rzeczywicie uywana,  lub  wylczajc
       je, wskazujc, e wlaciwo nie jest uywana (np.  %option noyymore).

       Trzy opcje pobieraj wartoci lacuchowe, offsetowane znakiem '=':

           %option outfile="ABC"

       jest rownowane -oABC, a

           %option prefix="XYZ"

       jest rownowane -PXYZ.  Poza tym,

           %option yyclass="foo"

       dotyczy  tylko  skanerow  C++ (opcja -+).  Mowi to fleksowi, e foo jest
       wyprowadzone jako podklasa yyFlexLexer, wic flex bdzie umieszczal twoje
       akcje  w funkcji skladowej foo::yylex() zamiast w yyFlexLexer::yylex().
       Powoduje to  te  generowanie  funkcji  skladowej  yyFlexLexer::yylex(),
       emitujcej    po    wywolaniu    bld    dzialania    (przez    wywolanie
       yyFlexLexer::LexerError()).  Dla dalszych  informacji  zobacz  te  niej
       Generowanie Skanerow C++.

       Istniej  opcje  dla  purystow,  nie  chccych  widzie w swoich skanerach
       niepotrzebnych procedur. Kada z nastpujcych opcji (np.   (np.,  %option
       nounput),  powoduje,  e  dana  procedura nie pojawia si w wygenerowanym
       skanerze:

           input, unput
           yy_push_state, yy_pop_state, yy_top_state
           yy_scan_buffer, yy_scan_bytes, yy_scan_string

       (chocia yy_push_state() i podobne i tak nie pojawi si dopoki nie uyjesz
       %optionstack).

ROZWAANIA NAD WYDAJNOCI

       Podstawowym  zadaniem  przy  projektowaniu  fleksa  bylo zapewnienie, e
       bdzie generowal  wydajne  skanery.  Zostal  zoptymalizowany  do  dobrej
       wspolpracy  z  wielkimi  zestawami  regul.  Poza omawianymi ju wplywami
       opcji kompresji -C, istnieje jeszcze kilka akcji/opcji  wplywajcych  na
       wydajno. S to, od najkosztowniejszej do najmniej kosztownej:

           REJECT
           %option yylineno
           arbitralny wiszcy kontekst

           zestawy wzorcow, wymagajce cofania
           %array
           %option interactive
           %option always-interactive

           '^' operator rozpoczcia linii
           yymore()

       z  ktorych  pierwsze  trzy  s  bardzo  kosztowne, a ostatnie dwa w miar
       tanie.   Zauwa  te,  e  unput()  jest  implementowane  jako   wywolanie
       procedurowe,  ktore  prawdopodobnie  wykonuje  sporo pracy, podczas gdy
       yyless() jest tanim makrem; wic jeli wstawiasz  z  powrotem  nadmiarowy
       wyskanowany tekst, uyj yyless().

       REJECT  powinno  by  unikane za wszelk cen z punktu widzenia wydajnoci.
       Jest to szczegolnie kosztowna opcja.

       Pozbycie si cofania jest  trudne  i  moe  czsto  prowadzi  do  bldow  w
       skomplikowanych  skanerach.  W praktyce zaczyna si od uycia flagi -b do
       wygenerowania pliku lex.backup.  Na przyklad dla wejcia

           %%
           foo        return TOK_KEYWORD;
           foobar     return TOK_KEYWORD;

       plik ten wyglda tak:

           State #6 is non-accepting -
            associated rule line numbers:
                  2       3
            out-transitions: [ o ]
            jam-transitions: EOF [ \001-n  p-\177 ]

           State #8 is non-accepting -
            associated rule line numbers:
                  3
            out-transitions: [ a ]
            jam-transitions: EOF [ \001-`  b-\177 ]

           State #9 is non-accepting -
            associated rule line numbers:
                  3
            out-transitions: [ r ]
            jam-transitions: EOF [ \001-q  s-\177 ]

           Compressed tables always back up.

       Pierwszych kilka linii mowi, e istnieje stan skanera, w ktorym  moe  on
       przyj  'o',  lecz nie moe przyj innego znaku i e w tym stanie aktualnie
       skanowany tekst nie pasuje do adnej reguly. Stan ten pojawia si podczas
       proby  dopasowania  regul z linijek 2 i 3 pliku wejciowego. Jeli skaner
       jest w tym stanie i odczyta cokolwiek innego ni 'o', to bdzie musial si
       cofn  i okreli, ktora regula pasuje. Po chwili skrobania si w glow mona
       zauway, e musi to by stan, gdy skaner zobaczyl  "fo".  W  tej  sytuacji
       otrzymanie  czegokolwiek  innego  ni 'o' spowoduje cofnicie do prostego
       dopasowania 'f' (regula domylna).

       Komentarz odnonie stanu #8 mowi, e  istnieje  problem  przy  skanowaniu
       "foob". Rzeczywicie, jeli pojawi si dowolny znak inny ni 'a', to skaner
       bdzie musial si cofn do przyjmowania "foo". Podobnie sprawa  ma  si  ze
       stanem #9, mowicym o "fooba", po ktorym nie nastpuje 'r'.

       Ostatni  komentarz przypomina nam, e usuwanie cofania nie ma sensu jeli
       nie uywamy -Cf lub -CF, gdy nie  daje  to  adnego  zysku  wydajnoci  na
       skanerach kompresowanych.

       Sposobem usuwania cofania jest dodawanie regul dla "bldow":

           %%
           foo         return TOK_KEYWORD;
           foobar      return TOK_KEYWORD;

           fooba       |
           foob        |
           fo          {
                       /* falszywy alarm, nie jest to slowo kluczowe */
                       return TOK_ID;
                       }

       Eliminowanie  cofania  mona przeprowadzi rownie przy uyciu reguly "lap-
       wszystko":

           %%
           foo         return TOK_KEYWORD;
           foobar      return TOK_KEYWORD;

           [a-z]+      return TOK_ID;

       Jest to, tam gdzie mona je zastosowa, najlepsze rozwizanie.

       Komunikaty cofania  czsto  ukladaj  si  w  kaskady.  W  skomplikowanych
       zbiorach  regul  mona  dosta  setki  komunikatow. Mimo to, jeli mona je
       zdeszyfrowa, to ich usuwanie wymaga tylko tuzina regul (latwo si jednak
       pomyli  i spowodowa, e regula obslugi bldu bdzie pasowa do prawidlowego
       tokena.  Moliwe,  e  przyszle  implementacje  fleksa  bd  automatycznie
       zajmowaly si usuwaniem cofania).

       Wane  jest  pamitanie,  e  korzyci z eliminacji tego problemu zyskujesz
       dopiero po zlikwidowaniu kadej  instancji  cofania.  Pozostawienie  cho
       jednej oznacza, e nie zyskujesz niczego.

       Zmienny  wiszcy  kontekst  (gdzie zarowno prowadzca jak i koczca cz nie
       maj ustalonej dlugoci) wprowadza utrat wydajnoci zblion do REJECT (tzn.
       znaczn). Dlatego gdy tylko mona, to zapisz tak regul:

           %%
           mouse|rat/(cat|dog)   run();

       jako:

           %%
           mouse/cat|dog         run();
           rat/cat|dog           run();

       lub jako

           %%
           mouse|rat/cat         run();
           mouse|rat/dog         run();

       zwro uwag, e specjalna akcja '|' nie powoduje adnych oszczdnoci, a wrcz
       moe pogorszy spraw (zobacz niej Niedostatki / Bldy).

       Innym obszarem, gdzie uytkownik moe zwiksza wydajno skanera jest to,  e
       im  dlusze  s dopasowywane tokeny, tym szybciej dziala skaner. Jest tak
       dlatego, e przetwarzanie dlugich  tokenow  wikszoci  znakow  wejciowych
       zachodzi   w   wewntrznej  (krotkiej)  ptli  skanujcej  i  rzadko  musi
       przechodzi  przez  dodatkow  prac  zwizan   z   ustawianiem   rodowiska
       skanujcego  (np.  yytext) dla akcji. Przypomnij sobie skaner komentarzy
       C:

           %x comment
           %%
                   int line_num = 1;

           "/*"         BEGIN(comment);

           <comment>[^*\n]*
           <comment>"*"+[^*/\n]*
           <comment>\n             ++line_num;
           <comment>"*"+"/"        BEGIN(INITIAL);

       Mona to przyspieszy nastpujco:

           %x comment
           %%
                   int line_num = 1;

           "/*"         BEGIN(comment);

           <comment>[^*\n]*
           <comment>[^*\n]*\n      ++line_num;
           <comment>"*"+[^*/\n]*
           <comment>"*"+[^*/\n]*\n ++line_num;
           <comment>"*"+"/"        BEGIN(INITIAL);

       Teraz zamiast sytuacji, gdzie nowa linia wymaga przetwarzania  nastpnej
       akcji,  rozpoznawanie  nowych  linii  jest "rozrzucone" na inne reguly.
       Umoliwia to zachowanie jak najdluszego dopasowania. Zauwa, e  dodawanie
       regul nie spowalnia skanera! Jego szybko jest niezalena od liczby regul
       i (w porownaniu do rozwaa z pocztku sekcji) ich stopnia  skomplikowania
       (z zastrzeeniem do operatorow takich jak '*' i '|').

       Ostateczny  przyklad  przyspieszania  skanera: zalomy, e chcesz skanowa
       plik zawierajcy identyfikatory i slowa kluczowe w  liczbie  jednego  na
       lini,  bez  adnych  obcych  znakow  i chcesz rozpoznawa wszystkie slowa
       kluczowe.  Naturalnym odruchem pocztkowym jest:

           %%
           asm      |
           auto     |
           break    |
           ... etc ...
           volatile |
           while    /* to jest slowo kluczowe */

           .|\n     /* a to nie... */

       Aby wyeliminowa ledzenie wstecz, wprowad regul lap-wszystko:

           %%
           asm      |
           auto     |
           break    |
           ... etc ...
           volatile |
           while    /* to slowo kluczowe */

           [a-z]+   |
           .|\n     /* a to nie... */

       Obecnie, jeli mamy zagwarantowane,  e  mamy  dokladnie  jedno  slowo  w
       linii, moemy zredukowa calkowit liczb dopasowa o polow przez wlczanie w
       rozpoznawanie tokenow lapanie nowych linii.

           %%
           asm\n    |
           auto\n   |
           break\n  |
           ... etc ...
           volatile\n |
           while\n  /* to slowo kluczowe */

           [a-z]+\n |
           .|\n     /* a to nie... */

       Trzeba by tu ostronym, gdy wlanie wprowadzilimy do skanera  cofanie.  W
       szczegolnoci,  jeli  my wiemy, e w wejciu nie bdzie nigdy znakow innych
       ni litery i nowe linie, to flex nie moe tego wiedzie i  bdzie  planowal
       ewentualno  cofania  podczas  skanowania  tokenu  w  rodzaju "auto", po
       ktorym  nie  nastpi  nowa  linia  lub  litera.  W  poprzednim   wypadku
       nastpiloby  po  prostu  dopasowanie  reguly  "auto",  lecz teraz nie ma
       "auto", ale  "auto\n".  Aby  wyeliminowa  moliwo  cofania,  moemy  albo
       zduplikowa  wszystkie  reguly  bez kocowych nowych linii albo, jeli nie
       spodziewamy si takiego wejcia i nie [interesuje nas] jego klasyfikacja,
       moemy wprowadzi regul lap-wszystko, ktora nie zawiera nowej linii.

           %%
           asm\n    |
           auto\n   |
           break\n  |
           ... etc ...
           volatile\n |
           while\n  /* to slowo kluczowe */

           [a-z]+\n |
           [a-z]+   |
           .|\n     /* a to nie... */

       Po  kompilacji  z -Cf, jest to prawie tak szybkie, jak tylko moliwe dla
       fleksa dla tego problemu.

       Ostatnia uwaga: flex jest wolny przy dopasowywaniu NUL-ow,  szczegolnie
       jeli  token  zawiera  ich  wiele.   Najlepiej  pisa reguly, dopasowujce
       kr'otkie fragmenty takich tekstow.

       Kolejna ostatnia uwaga o wydajnoci: jak wspomniano wyej  w  sekcji  Jak
       Dopasowywane   jest  Wejcie,  dynamiczne  zmiany  rozmiarow  yytext  do
       przyjmowania duych tokenow jest powolne, gdy  obecnie  wymaga  by  taki
       token byl reskanowany od pocztku. Tak wic jeli wydajno jest istotna, to
       powiniene dopasowywa "due"  fragmenty  tekstu,  lecz  nie  "olbrzymie".
       Granic midzy tymi pojciami jest okolo 8K znakow/token.

GENEROWANIE SKANER'OW C++

       flex daje dwie drogi tworzenia skanerow przeznaczonych dla C++. Pierwsz
       z nich jest proste skompilowanie fleksowego  skanera  kompilatorem  C++
       zamiast  kompilatora  C.  Nie powiniene napotka adnych bldow kompilacji
       (jeli si pojawi, to zglo  to  pod  adres  wskazany  niej,  w  sekcji  o
       autorze). Moesz wowczas w akcjach swoich regul uywa kodu C++ zamiast C.
       Zauwa, e domylnym rodlem dla skanera pozostaje yyin, a  domylnym  echem
       jest   wci   yyout.   Obydwa  urzdzenia  s  zmiennymi  FILE  *,  a  nie
       strumieniami C++.

       Mona te uy fleksa do generowania klasy skanera C++. Sluy do tego  opcja
       -+  (lub,  rownowanie  %option  c++), co jest przyjmowane automatycznie
       jeli nazwa pliku wykonywalnego fleksa koczy si plusem, jak np.  flex++.
       Przy  uyciu  tej opcji, flex generuje skaner do pliku lex.yy.cc zamiast
       lex.yy.c.  Generowany skaner zawiera plik naglowkowy FlexLexer.h, ktory
       definiuje interfejsy do dwoch klas C++.

       Pierwsza  klasa,  FlexLexer,  daje  abstrakcyjn  klas  bazow, definiujc
       ogolny interfejs klasy skanera.  Daje nastpujce funkcje skladowe:

       const char* YYText()
              zwraca tekst ostatnio dopasowanego tokenu, rownowanik yytext.

       int YYLeng()
              zwraca dlugo ostatnio dopasowanego tokenu, rownowanik yyleng.

       int lineno() const
              zwraca  numer  aktualnej   linii   wejciowej   (zobacz   %option
              yylineno), lub 1 jeli %option yylineno nie zostalo uyte.

       void set_debug( int flag )
              ustawia  flag  debuggujc  dla skanera, rownowanik przypisania do
              yy_flex_debug (zobacz wyej sekcj o opcjach). Zauwa, e aby  wlcza
              w  skanerze  informacje  diagnostyczne,  musisz  skompilowa go z
              uyciem %option debug.

       int debug() const
              zwraca biece ustawienie flagi debuggujcej.

       Udostpniane s  te  funkcje  skladowe  rownowane  yy_switch_to_buffer(),
       yy_create_buffer()  (chocia pierwszym argumentem jest wskanik istream*,
       a nie FILE*), yy_flush_buffer(), yy_delete_buffer()  i  yyrestart()  (i
       znowu, pierwszym argumentem jest wskanik istream*).

       Kolejn klas zdefiniowan w FlexLexer.h jest yyFlexLexer, ktory jest klas
       pochodn FlexLexer.  Zaiwera nastpujce dodatkowe funkcje skladowe:

       yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 )
              buduje obiekt yyFlexLexer stosujc podane strumienie jako  wejcie
              i  wyjcie.  Jeli nie zostan podane, to strumienie bd odpowiadaly
              odpowiednio cin i cout.

       virtual int yylex()
              odgrywa t sam rol co yylex()  dla  normalnych  skanerow  fleksa:
              skanuje  strumie  wejciowy,  konsumuje tokeny a akcja reguly nie
              zwroci wartoci. Jeli z  yyFlexLexer  wyprowadzisz  podklas  S  i
              zechcesz  dosta  si do funkcji i zmiennych skladowych S z wntrza
              yylex(), to musisz uy %option yyclass="S" by poinformowa fleksa,
              e  bdziesz  uywa  podklasy  zamiast  yyFlexLexer.  W tym wypadku
              zamiast generowa yyFlexLexer::yylex(), flex generuje  S::yylex()
              (oraz   generuje   prosty   yyFlexLexer::yylex(),   ktory   wola
              yyFlexLexer::LexerError() po wywolaniu).

       virtual void switch_streams(istream* new_in = 0,
              ostream* new_out = 0) przypisuje yyin do new_in (jeli jest  nie-
              nil)  oraz  yyout  do  new_out  (ditto),  kasujc poprzedni bufor
              wejciowy jeli przypisywana jest nowa warto yyin .

       int yylex( istream* new_in, ostream* new_out = 0 )
              najpierw przelcza strumienie  wejciowe  poprzez  switch_streams(
              new_in, new_out ), a nastpnie zwraca warto yylex().

       Poza tym, yyFlexLexer definiuje nastpujce chronione (protected) funkcje
       wirtualne, ktore mona przedefiniowa w klasach pochodnych, by  dostosowa
       skaner:

       virtual int LexerInput( char* buf, int max_size )
              odczytuje  maksymalnie  max_size  znakow  do  buf i zwraca liczb
              odczytanych znakow. Aby wskaza koniec  wejcia  zwracane  jest  0
              znakow.  Zauwa,  e  skanery "interaktywne" (zobacz flagi -B oraz
              -I)   definiuj   makro   YY_INTERACTIVE.    Jeli   redefiniujesz
              LexerInput()  i potrzebujesz bra rone akcje, zalenie od tego czy
              skaner skanuje rodlo interaktywne czy  nie,  to  moesz  sprawdza
              obecno tej nazwy poprzez #ifdef.

       virtual void LexerOutput( const char* buf, int size )
              zapisuje  size  znakow  z bufora buf ktory, o ile jest zakoczony
              zerem, moe zawiera te "wewntrzne" zera jeli reguly  skanera  mog
              lapa tekst z wewntrznymi zerami.

       virtual void LexerError( const char* msg )
              zglasza  komunikat  bldu krytycznego. Domylna wersja tej funkcji
              zapisuje  komunikat  do  strumienia  cerr  i   koczy   dzialanie
              programu.

       Zauwa, e obiekt yyFlexLexer zawiera swoj pe/lny stan skanowania. Tak wic
       mona  uywa  takich  obiektow  do  tworzenia  wielobienych   (reentrant)
       skanerow.  Moesz  uywa wielu instancji tej samej klasy yyFlexLexer, jak
       rownie moesz w jednym programie lczy wiele klas skanerow w calo, uywajc
       opisanej wyej opcji -P .

       Dla  skanerow  C++  nie  jest  dostpna  wlaciwo %array, trzeba wic uywa
       %pointer (tj. wartoci domylnej).

       Oto przyklad prostego skanera C++:

               // Przyklad uycia klasy skanera C++

           %{
           int mylineno = 0;
           %}

           string  \"[^\n"]+\"

           ws      [ \t]+

           alpha   [A-Za-z]
           dig     [0-9]
           name    ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])*
           num1    [-+]?{dig}+\.?([eE][-+]?{dig}+)?
           num2    [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)?
           number  {num1}|{num2}

           %%

           {ws}    /* pomi spacje i tabulacje */

           "/*"    {
                   int c;

                   while((c = yyinput()) != 0)
                       {
                       if(c == '\n')
                           ++mylineno;

                       else if(c == '*')
                           {
                           if((c = yyinput()) == '/')
                               break;
                           else
                               unput(c);
                           }
                       }
                   }

           {number}  cout << "number " << YYText() << '\n';

           \n        mylineno++;

           {name}    cout << "name " << YYText() << '\n';

           {string}  cout << "string " << YYText() << '\n';

           %%

           int main( int /* argc */, char** /* argv */ )
               {
               FlexLexer* lexer = new yyFlexLexer;
               while(lexer->yylex() != 0)
                   ;
               return 0;
               }
       Jeli chcesz tworzy wiele (ronych) klas leksera, powiniene uy  flagi  -P
       (lub  opcji  prefiks=)  do  zmiany  nazwy  kadego  yyFlexLexer  na inny
       xxFlexLexer.  Nastpnie moesz  zalcza  <FlexLexer.h>  do  swoich  innych
       rodel,  raz  na  klas  leksera,  zmieniajc  najpierw nazw yyFlexLexer w
       nastpujcy sposob:

           #undef yyFlexLexer
           #define yyFlexLexer xxFlexLexer
           #include <FlexLexer.h>

           #undef yyFlexLexer
           #define yyFlexLexer zzFlexLexer
           #include <FlexLexer.h>

       o ile (na przyklad) uyjesz opcji %option  prefix="xx"  dla  jednego  ze
       swoich skanerow, a %option prefix="zz" dla drugiego.

       WANE:  obecna  posta klasy skanujcej jest eksperymentalna i moe zmienia
       si midzy glownymi wydaniami.

NIEZGODNOCI Z LEX I POSIX

       flex  jest  przerobk  narzdzia  lex  z  AT&T  Unix  (jednake  obie   te
       implementacje  nie  maj  wspolnego  kodu). Posiada pewne rozszerzenia i
       niezgodnoci,  ktore  s  istotne  dla  tych,  ktorzy  chc  pisa  skanery
       dzialajce  z  oboma.  Flex jest w pelni zgodny ze specyfikacj POSIX lex
       poza szczegolem, e gdy uywa %pointer (domylne),  to  wywolanie  unput()
       niszczy zawarto yytext, co jest niezgodne ze specyfikacj POSIX.

       W  sekcji tej omowimy wszystkie znane obszary niezgodnoci fleksa z AT&T
       lex i specyfikacj POSIX.

       fleksowa opcja -l  wlcza  maksymaln  zgodno  z  oryginalnym  AT&T  lex,
       okupujc  to  jednak  znacznymi stratami wydajnoci generowanego skanera.
       Niej zaznaczymy, ktore niezgodnoci mona pokona uywajc opcji -l.

       flex jest w pelni zgodny z leksem poza nastpujcymi wyjtkami:

       -      Nieudokumentowana  zmienna  wewntrzna  skanera  lex   o   nazwie
              yylineno nie jest obslugiwana bez -l lub %option yylineno.

              yylineno  powinno by obslugiwane na poziomie buforowym, a nie na
              skanerowym (pojedyncza zmienna globalna).

              yylineno nie jest czci specyfikacji POSIX.

       -      Procedura input() nie jest redefiniowalna chocia moe  by  wolana
              do  czytania  znakow nastpujcym po tym, co dopasowano do reguly.
              Jeli input() napotka koniec pliku, to wykonywane  jest  normalne
              przetwarzanie   yywrap().    ``Prawdziwy''   koniec  pliku  jest
              sygnalizowany przez input() zwroceniem wartoci EOF.

              Wejcie  jest  natomiast  sterowane  przez   definiowanie   makra
              YY_INPUT.

              Ograniczenie  fleksa,  e  input()  nie moe by redefiniowany jest
              zgodne ze specyfikacj POSIX, ktora po prostu nie  okrela  innego
              adnego  sposobu  sterowania wejciem skanera ni poprzez dokonanie
              pocztkowego przypisania do yyin.

       -      Procedura unput() nie jest redefiniowalna. Ograniczenie to  jest
              zgodne z POSIX.

       -      Skanery fleksa nie s tak wielobiene (reentrant) jak skanery lex.
              W szczegolnoci, jeli masz interaktywny skaner i obslug  przerwa,
              ktora  robi dlugi skok ze skanera, a skaner jest nastpnie wolany
              ponownie, to moesz uzyska nastpujcy komunikat:

                  fatal flex scanner internal error--end of buffer missed

              Aby wej na nowo do skanera, uyj najpierw

                  yyrestart( yyin );

              Zauwa, e wywolanie to wyrzuci wszelkie buforowane wejcie; zwykle
              jednak nie jest to problem przy skanerach interaktywnych.

              Zauwa  te,  e  klasy  skanerow C++ s wielobiene (reentrant), wic
              uywajc opcji C++ powiniene ich uywa. Zobacz sekcj o  generowaniu
              skanerow C++.

       -      output() nie jest obslugiwany. Wyjcie makra ECHO jest wykonywane
              do wskanika plikowego yyout (domylnie stdout).

              output() nie jest czci specyfikacji POSIX.

       -      lex nie obsluguje wykluczajcych warunkow pocztkowych  (%x),  cho
              znajduj si one w specyfikacji POSIX.

       -      Przy  rozwijaniu definicji, flex ujmuje je w nawiasy.  W leksie,
              nastpujce:

                  NAME    [A-Z][A-Z0-9]*
                  %%
                  foo{NAME}?      printf( "Znalazlem\n" );
                  %%

              nie dopasuje si do lacucha "foo", gdy makro jest rozwijane  tak,
              e  regula  odpowiada  "foo[A-Z][A-Z0-9]*?",  a pierwszestwo jest
              takie, e '?'  jest  wizany  z  "[A-Z0-9]*".  We  fleksie  regula
              zostalaby  rozwinita  do  "foo([A-Z][A-Z0-9]*)?"  i lacuch "foo"
              zostalby dopasowany.

              Zauwa, e jeli definicja rozpoczyna si od ^ lub koczy si na $  to
              nie  jest  rozwijana  w  nawiasach,  aby  umoliwi tym operatorom
              pojawienie si  w  definicjach  bez  utraty  ich  znaczenia.  Ale
              operatory <s>, / i <<EOF>> nie mog by uywane w definicji fleksa.

              Uywanie  -l  skutkuje  leksowym zachowaniem braku nawiasow wokol
              definicji.

              POSIX nakazuje ujmowanie definicji w nawiasy.

       -      Niektore implementacje leksa umoliwiaj rozpoczynanie akcji regul
              w osobnej linii jeli wzorzec reguly ma doklejon bial spacj:

                  %%
                  foo|bar<tu spacja>
                    { foobar_action(); }

              flex nie obsluguje tej wlaciwoci.

       -      Leksowe  %r  (generuj  skaner  Ratfor) nie jest obslugiwane. Nie
              jest czci specyfikacji POSIX.

       -      Po  wywolaniu  unput(),  yytext  jest   niezdefiniowane   a   do
              dopasowania  nastpnego  tokenu,  chyba  e  skaner  uywa  %array.
              Inaczej ma si sprawa z leksem lub specyfikacj  POSIX.  Opcja  -l
              zalatwia t niezgodno.

       -      Pierwszestwo operatora {} (zakresu numerycznego) jest inne.  lex
              interpretuje "abc{1,3}" jako "dopasuj  1,  2  lub  3  pojawienia
              'abc'",  a  flex interpretuje to jako "dopasuj 'ab' z doklejonym
              jednym, dwoma lub trzema znakami  'c'".  Interpretacja  fleksowa
              jest zgodna ze specyfikacj POSIX.

       -      Pierwszestwo operatora ^ jest inne.  lex interpretuje "^foo|bar"
              jako  "dopasuj  albo  'foo'   z   pocztku   linii   albo   'bar'
              gdziekolwiek",  podczas  gdy flex rozumie to jako "dopasuj 'foo'
              lub 'bar' jeli pojawi si  na  pocztku  linii".  To  drugie  jest
              zgodne ze specyfikacj POSIX.

       -      Specjalne deklaracje rozmiaru-tablicy, takie jak %a, obslugiwane
              przez lex nie s wymagane przez skanery fleksa; flex je ignoruje.

       -      Nazwa FLEX_SCANNER jest #definiowana, wic skanery mog by  pisane
              z  przeznaczeniem  do  uycia  z  fleksem  lub  leksem.   Skanery
              zawieraj rownie  YY_FLEX_MAJOR_VERSION  i  YY_FLEX_MINOR_VERSION
              wskazujc na wersj fleksa, ktora wygenerowala skaner (na przyklad
              dla wydania 2.5 definiowane s odpowiednio liczby 2 i 5).

       Nastpujce wlaciwoci fleksa nie  s  zawarte  w  specyfikacjach  lex  ani
       POSIX:

           Skanery C++
           %option
           zakresy warunkow pocztkowych
           stosy warunkow pocztkowych
           skanery interaktywne/nieinteraktywne
           yy_scan_string() i koledzy
           yyterminate()
           yy_set_interactive()
           yy_set_bol()
           YY_AT_BOL()
           <<EOF>>
           <*>
           YY_DECL
           YY_START
           YY_USER_ACTION
           YY_USER_INIT
           dyrektywy #line
           %{} wokol akcji
           wiele akcji w linii

       plus prawie wszystkie flagi fleksa. Ostatnia wlaciwo listy odnosi si do
       faktu,  e  we  fleksie  mona  wstawia  wiele  akcji  do  jednej  linii,
       rozdzielajc je rednikami, podczas gdy w leksie, nastpujca instrukcja

           foo    handle_foo(); ++num_foos_seen;

       jest (raczej niespodziewanie) obcinana do

           foo    handle_foo();

       flex  nie  obcina  akcji.  Akcje  ktore  nie  s  objte klamrami kocz si
       zwyczajnie na kocu linii.

DIAGNOSTYKA

       warning,  rule  cannot  be  matched  (ostrzeenie,  regula  nie  moe  by
       dopasowana)  wskazuje,  e  podana  regula  nie  moe  by  dopasowana gdy
       wystpuje za  innymi  regulami,  ktore  zawsze  dopasuj  jej  tekst.  Na
       przyklad  nastpujce foo nie moe by dopasowane, gdy pojawia si po regule
       lap-wszystko:

           [a-z]+    got_identifier();
           foo       got_foo();

       Uycie w skanerze REJECT powstrzyma to ostrzeenie.

       warning, -s option given but default rule can be  matched  (ostrzeenie,
       podano  opcj  -s,  lecz  dopasowana  moe  by regula domylna) oznacza, e
       moliwe jest (przypuszczalnie tylko w konkretnym warunku pocztkowym),  e
       regula domylna (dopasowania dowolnego znaku) jest jedyn, ktora dopasuje
       si do konkretnego wejcia. Poniewa podano -s, zaklada si, e nie jest  to
       celowe.

       reject_used_but_not_detected undefined lub yymore_used_but_not_detected
       undefined (niezdefiniowana fraza pierwsza lub druga) - te bldy pojawiaj
       si  podczas kompilacji. Wskazuj one, e skaner uywa REJECT lub yymore(),
       lecz flex nie poinformowal o tym fakcie. Znaczy to, e flex przeskanowal
       pierwsze  dwie  sekcji w poszukiwaniu pojawienia si tych akcji, ale ich
       nie znalazl, bo jako je  przemycile  (np.  przez  plik  #include).  Uyj
       %option  reject  lub  %option  yymore  do wskazania fleksowi, e naprawd
       uywasz tych wlaciwoci.

       flex  scanner  jammed  -  skaner  skompilowany  z  -s  napotkal  lacuch
       wejciowy,  ktory  nie  zostal dopasowany do adnej z jego regul. Bld ten
       moe si pojawi te z powodu problemow wewntrznych.

       token too large, exceeds YYLMAX (token zbyt duy, przekracza  YYLMAX)  -
       twoj  skaner  uywa %array a jedna z jego regul dopasowala si do lacucha
       dluszego ni stala YYLMAX (domylnie 8K). Moesz zwikszy t warto zwikszajc
       #definicj stalej YYLMAX w sekcji definicji swojego wejcia fleksa.

       scanner  requires -8 flag to use the character 'x' (skaner wymaga flagi
       -8 do  uywania  znaku  'x')  -  specyfikacja  twojego  skanera  zawiera
       rozpoznawanie  znaku  8-bitowego  'x', a nie podana zostala flaga -8, w
       wyniku czego skaner uyl 7-bit z powodu  wykorzystania  opcji  kompresji
       tablic -Cf lub -CF.  Dla szczegolow zobacz dyskusj flagi -7.

       flex scanner push-back overflow - uyle unput() do wepchnicia z powrotem
       tak  dlugiego  tekstu,  e  bufor  skanera   nie   potrafil   przetrzyma
       wepchnitego  tekstu i biecego tokena w yytext.  Idealny skaner powinien
       dynamicznie zmieni rozmiar bufora, lecz obecnie tak si nie dzieje.

       input buffer overflow, can't enlarge buffer because scanner uses REJECT
       (przekroczenie  bufora  wejciowego  nie  moe powikszy bufora gdy skaner
       uywa REJECT) - skaner pracowal nad dopasowaniem bardzo duego  tokenu  i
       potrzebowal  rozszerzy  bufor  wejciowy.  Nie  dziala  to ze skanerami,
       uywajcymi REJECT.

       fatal flex scanner internal error--end of buffer missed (krytyczny  bld
       wewntrzny  skanera  flex  --  rozminito  si z kocem bufora) - Moe si to
       pojawi w skanerze, ktory jest  uruchomiony  po  dlugim  skoku  z  ramki
       aktywacji skanera. Przed powrotem do skanera uyj:

           yyrestart( yyin );

       albo, jak wspomniano wyej, przelcz si na uywanie skanerow C++.

       too  many  start  conditions  in  <>  construct!   (zbyt wiele warunkow
       pocztkowych w konstrukcji <>) - w  konstrukcji  <>  pojawilo  si  wicej
       warunkow  pocztkowych  ni  istnieje  w  rzeczywistoci (wic przynajmniej
       jeden z nich pojawil si dwukrotnie).

PLIKI

       -lfl   biblioteka, z ktor musz by lczone skanery.

       lex.yy.c
              generowany skaner (nazywany na niektorych systemach lexyy.c).

       lex.yy.cc
              generowana klasa skanera C++, po uyciu -+.

       <FlexLexer.h>
              plik naglowkowy definiujcy klas bazow skanera C++,  FlexLexer  i
              klas pochodn, yyFlexLexer.

       flex.skl
              skaner  szkieletowy.  Plik  ten jest uywany tylko przy budowaniu
              fleksa, nie przy jego uruchamianiu.

       lex.backup
              informacje wspierajce (backing-up) dla flagi -b  (nazywany  jest
              mianem lex.bck na niektorych systemach).

NIEDOSTATKI / B/LDY

       Niektore  wzorce  wiszcego  kontekstu nie mog by poprawnie dopasowane i
       generuj  komunikaty   ostrzegawcze   ("dangerous   trailing   context")
       (niebezpieczny   wiszcy   kontekst).  S  to  wzorce,  gdzie  zakoczenie
       pierwszej czci reguly dopasowuje si do pocztku drugiej czci, takie  jak
       "zx*/xy*",  gdzie  'x*'  dopasowuje  'x' na pocztku wiszcego kontekstu.
       (Zauwa, e projekt POSIX-a okrela, e dopasowany w takich wzorcach  tekst
       jest niezdefiniowany.)

       Dla  niektorych  regul wiszcego kontekstu, czci ktore s w rzeczywistoci
       okrelonej dlugoci nie s tak rozpoznawane. Prowadzi  to  do  wspomnianej
       wyej  straty wydajnoci. W szczegolnoci, czci uywajce '|' lub {n} (takie
       jak "foo{3}") zawsze s uwaane za zmienno-dlugociowe.

       Lczenie wiszcego  kontekstu  z  akcj  specjaln  '|'  moe  spowodowa,  e
       ustalony   (fixed)   wiszcy  kontekst  zostanie  zmieniony  w  bardziej
       kosztowny, zmienny wiszcy kontekst. Na przyklad nastpujce:

           %%
           abc      |
           xyz/def

       Uywanie unput() uszkadza yytext i yyleng, chyba e uyto dyrektywy %array
       lub opcji -l.

       Dopasowywanie  wzorcow  NUL-i jest znacznie wolniejsze ni dopasowywanie
       innych znakow.

       Dynamiczne zmiany rozmiaru bufora s wolne i wymagaj reskanowania calego
       tekstu dopasowanego dotd przez biecy (zwykle duy) token.

       Z powodu buforowania wejcia i czytania z wyprzedzeniem, nie mona lczy z
       regulami fleksa wywola <stdio.h>, np.  getchar().  Zamiast  tego  wolaj
       input().

       Wpisy  calej tablicy (total table entries) wymieniane przez flag -v nie
       zawieraj niektorych wpisow,  potrzebnych  do  okrelania,  ktora  regula
       zostala  dopasowana.  Liczba  wpisow  jeli  skaner nie uywa REJECT jest
       rowna liczbie stanow DFA, a w przeciwnym wypadku jest troch wiksza.

       REJECT nie moe by uywany z opcjami -f lub -F.

       Wewntrzne algorytmy fleksa wymagaj udokumentowania.

ZOBACZ TAKE

       lex(1), yacc(1), sed(1), awk(1).

       John Levine, Tony Mason, and Doug  Brown,  Lex  &  Yacc,  O'Reilly  and
       Associates.  Upewnij si, e bierzesz 2-gie wydanie.

       M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator

       Alfred  Aho,  Ravi  Sethi  and  Jeffrey  Ullman, Compilers: Principles,
       Techniques  and  Tools,  Addison-Wesley   (1986).    Opisuje   techniki
       dopasowywania  wzorcow  uywane  przez fleksa (deterministyczne automaty
       skoczone).

AUTOR

       Vern Paxson, z pomoc wielu pomyslow i  inspiracji  od  Vana  Jacobsona.
       Oryginaln  wersj napisal Jef Poskanzer.  Reprezentacja szybkiej tablicy
       jest czciow implementacj projektu Vana Jacobsona. Implementacja zostala
       wykonana przez Kevina Gonga and Verna Paxsona.

       Podzikowania  dla  wielu  beta  testerow,  komentatorow i kontrybutorow
       fleksa, z ktorych szczegolnie  zasluone  s  nastpujce  osoby:  Francois
       Pinard,  Casey  Leedom,  Robert Abramovitz, Stan Adermann, Terry Allen,
       David Barker-Plummer, John Basrai,  Neal  Becker,  Nelson  H.F.  Beebe,
       benson@odi.com,  Karl  Berry,  Peter  A.  Bigot, Simon Blanchard, Keith
       Bostic, Frederic Brehm, Ian Brockbank, Kin Cho, Nick Christopher, Brian
       Clapper,  J.T.  Conklin,  Jason  Coughlin, Bill Cox, Nick Cropper, Dave
       Curtis, Scott David Daniels, Chris G.  Demetriou,  Theo  Deraadt,  Mike
       Donahue,  Chuck  Doucette,  Tom Epperly, Leo Eskin, Chris Faylor, Chris
       Flatters, Jon Forrest, Jeffrey  Friedl,  Joe  Gayda,  Kaveh  R.  Ghazi,
       Wolfgang Glunz, Eric Goldman, Christopher M. Gould, Ulrich Grepel, Peer
       Griebel, Jan Hajic, Charles Hemphill, NORO  Hideo,  Jarkko  Hietaniemi,
       Scott  Hofmann,  Jeff  Honig, Dana Hudes, Eric Hughes, John Interrante,
       Ceriel Jacobs, Michal Jaegermann, Sakari Jalovaara, Jeffrey  R.  Jones,
       Henry  Juengst, Klaus Kaempf, Jonathan I. Kamens, Terrence O Kane, Amir
       Katz, ken@ken.hilco.com, Kevin B. Kenny, Steve Kirsch, Winfried Koenig,
       Marq  Kole, Ronald Lamprecht, Greg Lee, Rohan Lenard, Craig Leres, John
       Levine, Steve Liddle, David Loffredo, Mike Long, Mohamed el Lozy, Brian
       Madsen,  Malte,  Joe  Marshall,  Bengt  Martensson, Chris Metcalf, Luke
       Mewburn, Jim Meyering, R. Alexander Milowski, Erik Naggum, G.T.  Nicol,
       Landon  Noll,  James  Nordby,  Marc  Nozell,  Richard  Ohnemus, Karsten
       Pahnke, Sven Panne, Roland Pesch,  Walter  Pelissero,  Gaumond  Pierre,
       Esmond   Pitt,   Jef  Poskanzer,  Joe  Rahmeh,  Jarmo  Raiha,  Frederic
       Raimbault, Pat Rankin, Rick Richardson, Kevin Rodgers, Kai Uwe  Rommel,
       Jim  Roskind,  Alberto  Santini, Andreas Scherer, Darrell Schiebel, Raf
       Schietekat, Doug Schmidt, Philippe Schnoebelen, Andreas  Schwab,  Larry
       Schwimmer,  Alex  Siegel,  Eckehard  Stolz,  Jan-Erik  Strvmquist, Mike
       Stump, Paul Stuart, Dave Tallman,  Ian  Lance  Taylor,  Chris  Thewalt,
       Richard  M. Timoney, Jodi Tsai, Paul Tuinenga, Gary Weik, Frank Whaley,
       Gerhard Wilhelms, Kent Williams, Ken Yap,  Ron  Zellar,  Nathan  Zelle,
       David  Zuhn,  oraz  ci,  ktorych  nazwiska  wylecialy  z moich zdolnoci
       archiwizowania poczty, lecz ktorych wklad jest rownie wany.

       Keith Bostic, Jon Forrest, Noah Friedman, John  Gilmore,  Craig  Leres,
       John  Levine,  Bob  Mulcahy,  G.T.  Nicol, Francois Pinard, Rich Salz i
       Richard Stallman pomogli z ronymi problemami dystrybucji.

       Esmond Pitt and Earle Horton pomogl z wsparciem 8-bit; Benson Margulies
       i  Fred  Burke  pomogli  z  wsparciem  C++; Kent Williams i Tom Epperly
       pomogli z wsparciem klas C++; Ove Ewerlid pomogl  z  wsparciem  NUL-ow;
       Eric Hughes pomogl z wielokrotnymi buforami.

       Praca  ta byla pocztkowo wykonywana gdy bylem z Real Time Systems Group
       w Lawrence  Berkeley  Laboratory  w  Berkeley,  CA.  Wielkie  dziki  do
       wszystkich za wsparcie, ktore uzyskalem.

       Komentarze lij do vern@ee.lbl.gov.

INFORMACJE O T/LUMACZENIU

       Powysze  tlumaczenie  pochodzi z nieistniejcego ju Projektu Tlumaczenia
       Manuali i moe nie by aktualne. W razie zauwaenia ronic  midzy  powyszym
       opisem  a  rzeczywistym  zachowaniem  opisywanego programu lub funkcji,
       prosimy o zapoznanie si z oryginaln (angielsk) wersj strony podrcznika.