Amazon Best VPN GoSearch

Favicon OnWorks

freebsd-lex - Dalam Talian di Awan

Jalankan freebsd-lex dalam penyedia pengehosan percuma OnWorks melalui Ubuntu Online, Fedora Online, emulator dalam talian Windows atau emulator dalam talian MAC OS

Ini ialah arahan freebsd-lex yang boleh dijalankan dalam penyedia pengehosan percuma OnWorks menggunakan salah satu daripada berbilang stesen kerja dalam talian percuma kami seperti Ubuntu Online, Fedora Online, emulator dalam talian Windows atau emulator dalam talian MAC OS.

JADUAL:

NAMA


flex, lex - penjana penganalisis leksikal pantas

SINOPSIS


flex [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Awalan -Rangka] [--bantuan --versi]
[nama fail ...]

TINJAUAN


Manual ini menerangkan lentur, alat untuk menjana atur cara yang melakukan padanan corak
pada teks. Manual termasuk kedua-dua bahagian tutorial dan rujukan:

Penerangan Produk
gambaran ringkas alat tersebut

Beberapa Contoh Mudah

Format Fail Input

Corak
ungkapan biasa lanjutan yang digunakan oleh flex

Bagaimana Input Dipadankan
peraturan untuk menentukan apa yang telah dipadankan

Tindakan
bagaimana untuk menentukan perkara yang perlu dilakukan apabila corak dipadankan

Pengimbas Dijana
butiran mengenai pengimbas yang dihasilkan oleh flex;
bagaimana untuk mengawal sumber input

Mulakan Syarat
memperkenalkan konteks ke dalam pengimbas anda, dan
menguruskan "pengimbas mini"

Penampan Input Berbilang
bagaimana untuk memanipulasi pelbagai sumber input; bagaimana untuk
imbas daripada rentetan dan bukannya fail

Peraturan akhir fail
peraturan khas untuk memadankan penghujung input

Macro Pelbagai
ringkasan makro yang tersedia untuk tindakan

Nilai Tersedia Untuk Pengguna
ringkasan nilai yang tersedia untuk tindakan

Mengantaramuka Dengan Yacc
menyambungkan pengimbas fleksibel bersama-sama dengan penghurai yacc

Pilihan
pilihan baris perintah flex, dan "%option"
arahan

Pertimbangan Prestasi
bagaimana untuk membuat pengimbas anda berjalan secepat mungkin

Menjana Pengimbas C++
kemudahan (percubaan) untuk menjana C++
kelas pengimbas

Ketidakserasian Dengan Lex Dan POSIX
bagaimana flex berbeza daripada AT&T lex dan POSIX lex
standard

Diagnostik
mesej ralat yang dihasilkan oleh flex (atau pengimbas
ia menjana) yang maknanya mungkin tidak jelas

Fail
fail yang digunakan oleh flex

Kekurangan / Bug
masalah yang diketahui dengan flex

See Also
dokumentasi lain, alat berkaitan

Pengarang
termasuk maklumat hubungan

DESCRIPTION


flex adalah alat untuk menjana pengimbas: program yang mengenali corak leksikal dalam teks.
flex membaca fail input yang diberikan, atau input standardnya jika tiada nama fail diberikan, untuk a
perihalan pengimbas untuk dijana. Penerangan adalah dalam bentuk pasangan biasa
ungkapan dan kod C, dipanggil peraturan. flex menjana sebagai output fail sumber C, lex.yy.c,
yang mentakrifkan rutin yylex(). Fail ini disusun dan dipautkan dengan -ll perpustakaan ke
menghasilkan laksana. Apabila boleh laku dijalankan, ia menganalisis inputnya untuk kejadian
daripada ungkapan biasa. Setiap kali ia menemui satu, ia melaksanakan kod C yang sepadan.

SESETENGAH MUDAH CONTOH


Mula-mula beberapa contoh mudah untuk mendapatkan rasa cara seseorang menggunakannya lentur. Berikut flex
input menentukan pengimbas yang apabila ia menemui rentetan "nama pengguna" akan menggantikan
ia dengan nama log masuk pengguna:

%%
nama pengguna printf("%s", getlogin() );

Secara lalai, mana-mana teks yang tidak dipadankan dengan a flex pengimbas disalin ke output, jadi bersih
kesan pengimbas ini adalah untuk menyalin fail inputnya ke outputnya dengan setiap kejadian
"nama pengguna" dikembangkan. Dalam input ini, hanya terdapat satu peraturan. "nama pengguna" ialah pola
dan "printf" ialah tindakan. "%%" menandakan permulaan peraturan.

Berikut ialah satu lagi contoh mudah:

%{
int num_lines = 0, num_chars = 0;
%}

%%
\n ++bilangan_baris; ++num_chars;
. ++num_chars;

%%
main ()
{
yylex();
printf("# baris = %d, # aksara = %d\n",
num_lines, num_chars );
}

Pengimbas ini mengira bilangan aksara dan bilangan baris dalam inputnya (ia
tidak menghasilkan keluaran selain daripada laporan akhir mengenai kiraan). Baris pertama mengisytiharkan
dua global, "num_lines" dan "num_chars", yang boleh diakses kedua-duanya di dalam yylex() dan dalam
yang main () rutin diisytiharkan selepas "%%" kedua. Terdapat dua peraturan, satu yang sepadan
baris baharu ("\n") dan menambah kedua-dua kiraan baris dan kiraan aksara, dan satu lagi
sepadan dengan mana-mana aksara selain daripada baris baharu (ditunjukkan oleh ungkapan biasa ".").

Contoh yang agak rumit:

/* pengimbas untuk mainan bahasa seperti Pascal */

%{
/* perlukan ini untuk panggilan ke atof() di bawah */
#sertakan
%}

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

%%

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

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

jika|maka|mula|tamat|prosedur|fungsi {
printf("Kata kunci: %s\n", yytext );
}

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

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

"{"[^}\n]*"}" /* makan ulasan satu baris */

[ \t\n]+ /* makan ruang kosong */

. printf("Watak tidak dikenali: %s\n", yytext );

%%

utama( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* langkau nama program */
jika ( argc > 0 )
yyin = fopen( argv[0], "r" );
lagi
yyin = stdin;

yylex();
}

Ini adalah permulaan pengimbas mudah untuk bahasa seperti Pascal. Ia mengenal pasti
pelbagai jenis token dan melaporkan apa yang telah dilihatnya.

Butiran contoh ini akan diterangkan dalam bahagian berikut.

FORMAT OF THE INPUT FAIL


. flex fail input terdiri daripada tiga bahagian, dipisahkan oleh baris dengan hanya %% di dalamnya:

definisi
%%
peraturan
%%
kod pengguna

. definisi bahagian mengandungi pengisytiharan mudah nama definisi untuk memudahkan
spesifikasi pengimbas, dan pengisytiharan permulaan syarat, yang dijelaskan dalam a
bahagian kemudian.

Takrif nama mempunyai bentuk:

definisi nama

"Nama" ialah perkataan yang bermula dengan huruf atau garis bawah ('_') diikuti dengan sifar atau
lebih banyak huruf, digit, '_' atau '-' (sempang). Definisi diambil untuk bermula pada yang pertama
aksara bukan ruang putih mengikut nama dan terus ke hujung baris. The
takrifan kemudiannya boleh dirujuk menggunakan "{name}", yang akan berkembang ke
"(definisi)". Sebagai contoh,

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

mentakrifkan "DIGIT" sebagai ungkapan biasa yang sepadan dengan satu digit dan "ID" menjadi a
ungkapan biasa yang sepadan dengan huruf diikuti dengan sifar-atau-lebih huruf-atau-digit. A
rujukan seterusnya kepada

{DIGIT}+"."{DIGIT}*

sama dengan

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

dan sepadan dengan satu atau lebih digit diikuti dengan '.' diikuti dengan sifar atau lebih digit.

. peraturan seksyen flex input mengandungi satu siri peraturan borang:

aksi corak

di mana corak mestilah tidak disentuh dan tindakan mesti bermula pada baris yang sama.

Lihat di bawah untuk penerangan lanjut tentang corak dan tindakan.

Akhir sekali, bahagian kod pengguna hanya disalin ke lex.yy.c verbatim. Ia digunakan untuk
rutin teman yang memanggil atau dipanggil oleh pengimbas. Kehadiran bahagian ini
adalah pilihan; jika ia hilang, yang kedua %% dalam fail input mungkin juga dilangkau.

Dalam bahagian takrif dan peraturan, mana-mana lekukan teks atau teks yang disertakan %{ and %} is
menyalin verbatim ke output (dengan %{} dialih keluar). %{}'s mesti kelihatan tanpa inden
pada talian sendiri.

Dalam bahagian peraturan, sebarang teks inden atau %{} yang muncul sebelum peraturan pertama boleh digunakan
untuk mengisytiharkan pembolehubah yang setempat kepada rutin pengimbasan dan (selepas pengisytiharan)
kod yang akan dilaksanakan apabila rutin pengimbasan dimasukkan. Lain inden atau
%{} teks dalam bahagian peraturan masih disalin ke output, tetapi maknanya tidak baik-
ditakrifkan dan ia mungkin menyebabkan ralat masa kompilasi (ciri ini hadir untuk POSIX
pematuhan; lihat di bawah untuk ciri-ciri lain).

Dalam bahagian takrifan (tetapi bukan dalam bahagian peraturan), ulasan tidak berinden (iaitu, a
baris yang bermula dengan "/*") juga disalin secara verbatim ke output sehingga "*/" seterusnya.

CORAK


Corak dalam input ditulis menggunakan set lanjutan ungkapan biasa. Ini
ialah:

x sepadan dengan watak 'x'
. sebarang aksara (bait) kecuali baris baharu
[xyz] "kelas watak"; dalam kes ini, corak
sepadan sama ada 'x', 'y' atau 'z'
[abj-oZ] "kelas watak" dengan julat di dalamnya; perlawanan
a 'a', a 'b', sebarang huruf daripada 'j' melalui 'o',
atau 'Z'
[^AZ] "kelas aksara dinafikan", iaitu, sebarang aksara
tetapi mereka yang berada di dalam kelas. Dalam kes ini, mana-mana
aksara KECUALI huruf besar.
[^AZ\n] mana-mana aksara KECUALI huruf besar atau
baris baru
r* sifar atau lebih r, dengan r ialah sebarang ungkapan biasa
r+ satu atau lebih r
r? sifar atau satu r (iaitu, "r pilihan")
r{2,5} di mana-mana dari dua hingga lima r
r{2,} dua atau lebih r
r{4} tepat 4 r
{name} pengembangan takrifan "nama".
(lihat di atas)
"[xyz]\"foo"
rentetan literal: [xyz]"foo
\X jika X ialah 'a', 'b', 'f', 'n', 'r', 't' atau 'v',
maka tafsiran ANSI-C bagi \x.
Jika tidak, 'X' literal (digunakan untuk melarikan diri
pengendali seperti '*')
\0 aksara NUL (kod ASCII 0)
\123 aksara dengan nilai perlapanan 123
\x2a aksara dengan nilai perenambelasan 2a
(r) padankan dengan r; kurungan digunakan untuk mengatasi
keutamaan (lihat di bawah)

rs ungkapan biasa r diikuti oleh
ungkapan biasa s; dipanggil "penggabungan"

r|s sama ada an r atau an s

r/s an r tetapi hanya jika ia diikuti oleh s. The
teks yang dipadankan dengan s disertakan semasa menentukan
sama ada peraturan ini ialah "perlawanan paling lama",
tetapi kemudian dikembalikan kepada input sebelum ini
tindakan itu dilaksanakan. Jadi tindakan sahaja
melihat teks dipadankan dengan r. Jenis ini
corak dipanggil konteks belakang".
(Terdapat beberapa kombinasi r/s yang melentur
tidak boleh dipadankan dengan betul; lihat nota dalam
Bahagian Kekurangan / Pepijat di bawah berkenaan
"konteks jejak yang berbahaya".)
^r an r, tetapi hanya pada permulaan baris (iaitu,
apabila baru mula mengimbas, atau sejurus selepas a
baris baharu telah diimbas).
r$ an r, tetapi hanya pada penghujung baris (iaitu, just
sebelum baris baharu). Bersamaan dengan "r/\n".

Ambil perhatian bahawa tanggapan flex tentang "baris baharu" adalah tepat
apa sahaja pengkompil C yang digunakan untuk menyusun flex
mentafsirkan '\n' sebagai; khususnya, pada beberapa DOS
sistem anda mesti sama ada menapis \r's dalam
masukkan sendiri, atau gunakan r/\r\n secara eksplisit untuk "r$".

r an r, tetapi hanya dalam keadaan permulaan s (lihat
di bawah untuk perbincangan tentang syarat permulaan)
r
sama, tetapi dalam mana-mana keadaan permulaan s1,
s2, atau s3
<*>r an r dalam mana-mana keadaan permulaan, walaupun yang eksklusif.

< > akhir fail
< >
akhir fail apabila dalam keadaan mula s1 atau s2

Ambil perhatian bahawa dalam kelas aksara, semua pengendali ekspresi biasa kehilangan keistimewaan mereka
bermakna kecuali melarikan diri ('\') dan pengendali kelas aksara, '-', ']', dan, pada
permulaan kelas, '^'.

Ungkapan biasa yang disenaraikan di atas dikumpulkan mengikut keutamaan, dari tertinggi
keutamaan di bahagian atas hingga terendah di bahagian bawah. Mereka yang dikumpulkan bersama mempunyai persamaan
keutamaan. Sebagai contoh,

foo|bar*

adalah sama seperti

(foo)|(ba(r*))

kerana operator '*' mempunyai keutamaan yang lebih tinggi daripada penggabungan, dan penggabungan lebih tinggi
daripada selang seli ('|'). Oleh itu corak ini sepadan sama ada rentetan "foo" or yang
rentetan "ba" diikuti dengan r sifar atau lebih. Untuk memadankan "foo" atau sifar atau lebih "bar", gunakan:

foo|(bar)*

dan untuk memadankan sifar atau lebih "foo"'s-or-"bar":

(foo|bar)*

Selain aksara dan julat aksara, kelas aksara juga boleh mengandungi
kelas watak ungkapan. Ini adalah ungkapan yang disertakan di dalamnya [: and :] pembatas
(yang mesti muncul di antara '[' dan ']' kelas aksara; lain
unsur mungkin berlaku di dalam kelas watak juga). Ungkapan yang sah ialah:

[:alnum:] [:alpha:] [:kosong:]
[:cntrl:] [:digit:] [:graf:]
[:lower:] [:print:] [:punct:]
[:ruang:] [:atas:] [:xdigit:]

Ungkapan ini semuanya menetapkan satu set aksara yang setara dengan yang sepadan
piawai C ialahXXX fungsi. Sebagai contoh, [:alnum:] menunjuk watak-watak yang
isalnum() mengembalikan benar - iaitu, sebarang abjad atau angka. Sesetengah sistem tidak menyediakan
isblank(), jadi flex mentakrifkan [:kosong:] sebagai kosong atau tab.

Sebagai contoh, kelas aksara berikut semuanya setara:

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

Jika pengimbas anda tidak peka huruf besar-besaran (the -i bendera), kemudian [:atas:] and [:bawah:] adalah
bersamaan dengan [:alfa:].

Beberapa nota mengenai corak:

- Kelas aksara yang dinafikan seperti contoh "[^AZ]" di atas akan sepadan dengan a baris baru
melainkan "\n" (atau urutan pelarian yang setara) ialah salah satu aksara secara eksplisit
hadir dalam kelas aksara yang dinafikan (cth, "[^AZ\n]"). Ini tidak seperti berapa banyak
alat ekspresi biasa lain merawat kelas aksara yang dinafikan, tetapi malangnya
ketidakselarasan itu sudah berakar umbi dari segi sejarah. Memadankan baris baharu bermakna a
corak seperti [^"]* boleh memadankan keseluruhan input melainkan terdapat petikan lain dalam
input.

- Peraturan boleh mempunyai paling banyak satu contoh konteks tertinggal (pengendali '/' atau
operator '$'). Keadaan permulaan, '^', dan "< >" corak hanya boleh berlaku pada
permulaan corak, dan, serta dengan '/' dan '$', tidak boleh dikumpulkan
dalam kurungan. '^' yang tidak berlaku pada permulaan peraturan atau '$'
yang tidak berlaku pada penghujung peraturan kehilangan sifat istimewanya dan adalah
dianggap sebagai watak biasa.

Berikut adalah haram:

foo/bar$
foo bar

Ambil perhatian bahawa yang pertama ini, boleh ditulis "foo/bar\n".

Perkara berikut akan menyebabkan '$' atau '^' dianggap sebagai aksara biasa:

foo|(bar$)
foo|^bar

Jika yang dikehendaki ialah "foo" atau bar-diikuti-oleh-baris-baharu, yang berikut mungkin
digunakan (tindakan '|' khas dijelaskan di bawah):

foo |
bar$ /* tindakan pergi ke sini */

Helah yang serupa akan berfungsi untuk memadankan foo atau bar-di-permulaan-baris.

BAGAIMANA THE INPUT IS DIPADAKAN


Apabila pengimbas yang dihasilkan dijalankan, ia menganalisis inputnya mencari rentetan yang sepadan
mana-mana coraknya. Jika ia menemui lebih daripada satu padanan, ia memerlukan yang paling sepadan
teks (untuk peraturan konteks mengekor, ini termasuk panjang bahagian mengekor, genap
walaupun ia kemudiannya akan dikembalikan kepada input). Jika ia mendapati dua atau lebih padanan daripada
panjang yang sama, peraturan yang disenaraikan dahulu dalam flex fail input dipilih.

Setelah perlawanan ditentukan, teks yang sepadan dengan perlawanan (dipanggil token) is
tersedia dalam penunjuk aksara global yytext, dan panjangnya dalam global
integer yyleng. . tindakan sepadan dengan corak yang dipadankan kemudiannya dilaksanakan (lebih
penerangan terperinci tindakan berikut), dan kemudian baki input diimbas
satu lagi perlawanan.

Jika tiada padanan ditemui, maka lalai memerintah dilaksanakan: aksara seterusnya dalam input
dianggap dipadankan dan disalin ke output standard. Oleh itu, undang-undang yang paling mudah flex
input ialah:

%%

yang menjana pengimbas yang hanya menyalin inputnya (satu aksara pada satu masa) kepadanya
output.

Perhatikan bahawa yytext boleh ditakrifkan dalam dua cara yang berbeza: sama ada sebagai watak penunjuk atau sebagai
watak susunan. Anda boleh mengawal definisi yang mana flex menggunakan dengan memasukkan salah satu daripada
arahan khas %penunjuk or %array dalam bahagian pertama (takrifan) flex anda
input. Lalainya ialah %penunjuk, melainkan anda menggunakan -l pilihan keserasian lex, di mana
kes yytext akan menjadi tatasusunan. Kelebihan menggunakan %penunjuk adalah jauh lebih pantas
pengimbasan dan tiada limpahan penimbal apabila memadankan token yang sangat besar (melainkan anda kehabisan
ingatan dinamik). Kelemahannya ialah anda terhad dalam cara tindakan anda boleh
mengubah suai yytext (lihat bahagian seterusnya), dan memanggil ke unput() fungsi memusnahkan
membentangkan kandungan yytext, yang boleh menjadi sakit kepala porting yang agak besar apabila bergerak
antara berbeza lex versi.

Kelebihan %array ialah anda boleh mengubah suai yytext sesuka hati anda, dan
panggilan ke unput() jangan musnahkan yytext (lihat di bawah). Tambahan pula, sedia ada lex program
kadang-kadang akses yytext secara luaran menggunakan pengisytiharan borang:
aksara luar yytext[];
Takrifan ini adalah salah apabila digunakan dengan %penunjuk, tetapi betul untuk %array.

%array mentakrifkan yytext menjadi susunan YYLMAX aksara, yang lalai kepada adil
besar nilainya. Anda boleh menukar saiz dengan hanya #define'ing YYLMAX kepada nilai yang berbeza dalam
bahagian pertama anda flex input. Seperti yang dinyatakan di atas, dengan %penunjuk yytext berkembang
secara dinamik untuk menampung token besar. Walaupun ini bermakna anda %penunjuk pengimbas boleh
menampung token yang sangat besar (seperti memadankan keseluruhan blok ulasan), perlu diingat
bahawa setiap kali pengimbas mesti mengubah saiz yytext ia juga mesti mengimbas semula keseluruhan token daripada
permulaan, jadi pemadanan token sebegitu boleh terbukti perlahan. yytext buat masa ini tidak
berkembang secara dinamik jika panggilan ke unput() mengakibatkan terlalu banyak teks ditolak; sebaliknya,
ralat masa jalan terhasil.

Juga ambil perhatian bahawa anda tidak boleh menggunakan %array dengan kelas pengimbas C++ (the C ++ pilihan; lihat di bawah).

TINDAKAN


Setiap corak dalam peraturan mempunyai tindakan yang sepadan, yang boleh menjadi sebarang pernyataan C sewenang-wenangnya.
Corak berakhir pada aksara ruang kosong pertama yang tidak dilepaskan; baki baris
adalah tindakannya. Jika tindakan itu kosong, maka apabila corak dipadankan dengan token input
dibuang begitu saja. Sebagai contoh, berikut ialah spesifikasi untuk program yang memadam
semua kejadian "zap me" daripada inputnya:

%%
"tegur saya"

(Ia akan menyalin semua aksara lain dalam input ke output kerana ia akan dipadankan
mengikut peraturan lalai.)

Berikut ialah atur cara yang memampatkan berbilang kosong dan tab ke satu kosong, dan
membuang ruang putih yang terdapat di hujung baris:

%%
[ \t]+ putchar( ' ' );
[ \t]+$ /* abaikan token ini */

Jika tindakan itu mengandungi '{', maka tindakan itu berlangsung sehingga pengimbangan '}' ditemui, dan
tindakan itu mungkin melintasi berbilang baris. flex tahu tentang rentetan C dan ulasan dan tidak akan
tertipu dengan pendakap yang terdapat di dalamnya, tetapi juga membenarkan tindakan dimulakan %{ dan akan
pertimbangkan tindakan itu sebagai semua teks sehingga seterusnya %} (tidak kira pendakap biasa
dalam tindakan).

Tindakan yang terdiri semata-mata daripada bar menegak ('|') bermaksud "sama seperti tindakan untuk seterusnya
peraturan." Lihat di bawah untuk ilustrasi.

Tindakan boleh termasuk kod C sewenang-wenangnya, termasuk pulangan penyata untuk mengembalikan nilai kepada
apa sahaja yang dipanggil rutin yylex(). Setiap masa yylex() dipanggil ia meneruskan pemprosesan
token dari tempat terakhir ia berhenti sehingga ia sama ada mencapai penghujung fail atau laksana
pulangan.

Tindakan bebas untuk diubah suai yytext kecuali untuk memanjangkannya (menambah aksara padanya
tamat--ini akan menulis ganti aksara kemudian dalam aliran input). Ini bagaimanapun tidak
memohon apabila menggunakan %array (lihat di atas); kalau macam itu, yytext boleh diubah suai secara bebas dalam mana-mana
cara.

Tindakan bebas untuk diubah suai yyleng kecuali mereka tidak sepatutnya berbuat demikian jika tindakan itu juga termasuk
penggunaan yymore() (lihat di bawah).

Terdapat beberapa arahan khas yang boleh disertakan dalam tindakan:

- ECHO menyalin yytext ke output pengimbas.

- BEGIN diikuti dengan nama keadaan mula meletakkan pengimbas dalam
keadaan permulaan yang sepadan (lihat di bawah).

- REJEK mengarahkan pengimbas untuk meneruskan ke peraturan "kedua terbaik" yang sepadan
input (atau awalan input). Peraturan dipilih seperti yang diterangkan di atas dalam
"Bagaimana Input Dipadankan", dan yytext and yyleng sediakan dengan sewajarnya. Ia mungkin
sama ada menjadi satu yang sepadan dengan banyak teks seperti peraturan asal yang dipilih tetapi datang
nanti dalam flex fail input, atau fail yang kurang sepadan dengan teks. Sebagai contoh, yang
berikut akan mengira perkataan dalam input dan memanggil rutin special()
apabila "frob" dilihat:

int word_count = 0;
%%

frob istimewa(); TOLAK;
[^ \t\n]+ ++bilangan_perkataan;

Tanpa TOLAK, sebarang "frob" dalam input tidak akan dikira sebagai perkataan, kerana
pengimbas biasanya hanya melaksanakan satu tindakan bagi setiap token. Pelbagai TOLAK adalah
dibenarkan, masing-masing mencari pilihan terbaik seterusnya kepada peraturan yang sedang aktif. Untuk
contoh, apabila pengimbas berikut mengimbas token "abcd", ia akan menulis
"abcdabbaba" kepada output:

%%
a |
ab |
abc |
abcd ECHO; TOLAK;
.|\n /* makan mana-mana watak yang tiada tandingan */

(Tiga peraturan pertama berkongsi tindakan keempat kerana mereka menggunakan '|' khas
tindakan.) REJEK adalah ciri yang sangat mahal dari segi pengimbas
prestasi; jika ia digunakan dalam mana-mana daripada tindakan pengimbas ia akan menjadi perlahan semua of
padanan pengimbas. Tambahan pula, REJEK tidak boleh digunakan dengan -Cf or -CF
pilihan (lihat di bawah).

Perhatikan juga bahawa tidak seperti tindakan khas yang lain, REJEK ialah cawangan; kod
serta-merta mengikutinya dalam tindakan akan tidak dilaksanakan.

- yymore() memberitahu pengimbas bahawa pada kali berikutnya ia sepadan dengan peraturan, yang sepadan
token sepatutnya dilampirkan ke nilai semasa bagi yytext bukannya menggantikannya.
Sebagai contoh, diberikan input "mega-kludge" yang berikut akan menulis "mega-mega-
kludge" kepada output:

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

"mega-" pertama dipadankan dan digemakan dengan output. Kemudian "kludge" dipadankan, tetapi
"mega-" sebelum ini masih berkeliaran di awal yytext jadi ECHO
untuk peraturan "kludge" sebenarnya akan menulis "mega-kludge".

Dua nota mengenai penggunaan yymore(). Pertama, yymore() bergantung kepada nilai yyleng
mencerminkan saiz token semasa dengan betul, jadi anda tidak boleh mengubah suai yyleng jika anda
sedang menggunakan yymore(). Kedua, kehadiran yymore() dalam tindakan pengimbas memerlukan a
penalti prestasi kecil dalam kelajuan pemadanan pengimbas.

- yyless(n) mengembalikan semua kecuali yang pertama n aksara token semasa kembali ke
aliran input, di mana ia akan diimbas semula apabila pengimbas mencari yang seterusnya
sepadan. yytext and yyleng diselaraskan dengan sewajarnya (cth, yyleng sekarang akan menjadi
sama dengan n ). Sebagai contoh, pada input "foobar" perkara berikut akan ditulis
"foobarbar":

%%
foobar ECHO; yyless(3);
[az]+ ECHO;

Hujah 0 hingga yyless akan menyebabkan keseluruhan rentetan input semasa diimbas
sekali lagi. Melainkan anda telah menukar cara pengimbas akan memproses inputnya kemudiannya
(menggunakan BERMULA, sebagai contoh), ini akan menghasilkan gelung yang tidak berkesudahan.

Perhatikan bahawa yyless ialah makro dan hanya boleh digunakan dalam fail input flex, bukan dari yang lain
fail sumber.

- nyahput(c) meletakkan watak c kembali ke aliran input. Ia akan menjadi yang seterusnya
watak diimbas. Tindakan berikut akan mengambil token semasa dan menyebabkannya
untuk diimbas semula yang disertakan dalam kurungan.

{
int i;
/* Salin yytext kerana unput() menyampah yytext */
char *yycopy = strdup( yytext );
nyahput( ')' );
untuk ( i = yyleng - 1; i >= 0; --i )
unput( yycopy[i] );
nyahput( '(' );
percuma( yycopy );
}

Perhatikan bahawa sejak setiap unput() meletakkan watak yang diberikan kembali pada bermula daripada
aliran input, menolak rentetan ke belakang mesti dilakukan dari belakang ke hadapan.

Masalah berpotensi penting apabila menggunakan unput() adalah itu jika anda menggunakan %penunjuk (Yang
lalai), panggilan ke unput() memusnahkan kandungan yytext, bermula dengan yang paling kanan
watak dan memakan satu watak ke kiri dengan setiap panggilan. Jika anda memerlukan nilai
daripada yytext dikekalkan selepas panggilan ke unput() (seperti dalam contoh di atas), anda mesti sama ada
mula-mula salin di tempat lain, atau bina pengimbas anda menggunakan %array sebaliknya (lihat Bagaimana Input Itu
dipadankan).

Akhir sekali, ambil perhatian bahawa anda tidak boleh meletakkan semula EOF untuk cuba menandakan aliran input dengan
akhir fail.

- input() membaca aksara seterusnya daripada aliran input. Sebagai contoh, berikut
adalah salah satu cara untuk memakan ulasan C:

%%
"/*" {
int c;

untuk ( ; ; )
{
manakala ( (c = input()) != '*' &&
c != EOF )
; /* makan teks ulasan */

jika ( c == '*' )
{
manakala ( (c = input()) == '*' )
;
jika ( c == '/' )
pecah; /* jumpa penghujungnya */
}

jika ( c == EOF )
{
ralat("EOF dalam ulasan");
memecahkan;
}
}
}

(Perhatikan bahawa jika pengimbas disusun menggunakan C++, kemudian input() sebaliknya dirujuk
ke sebagai yyinput(), untuk mengelakkan pertembungan nama dengan C + + aliran dengan nama
input.)

- YY_FLUSH_BUFFER mengepam penimbal dalaman pengimbas supaya pada kali seterusnya
pengimbas cuba memadankan token, ia akan mengisi semula penimbal menggunakan YY_INPUT
(lihat Pengimbas Dijana, di bawah). Tindakan ini adalah kes khas yang lebih
umum yy_flush_buffer() fungsi, diterangkan di bawah dalam bahagian Input Berbilang
Penampan.

- tamat tempoh () boleh digunakan sebagai ganti pernyataan pulangan dalam tindakan. Ia
menamatkan pengimbas dan mengembalikan 0 kepada pemanggil pengimbas, menunjukkan "semua
selesai". Secara lalai, tamat tempoh () juga dipanggil apabila akhir fail adalah
dihadapi. Ia adalah makro dan boleh ditakrifkan semula.

THE DIJANA PEMARKAHAN


Pengeluaran flex ialah fail lex.yy.c, yang mengandungi rutin pengimbasan yylex(), a
bilangan jadual yang digunakan olehnya untuk memadankan token, dan beberapa rutin tambahan dan
makro. Secara lalai, yylex() diisytiharkan seperti berikut:

int yylex()
{
... pelbagai definisi dan tindakan di sini ...
}

(Jika persekitaran anda menyokong prototaip fungsi, maka ia akan menjadi "int yylex( void )".)
Takrifan ini boleh diubah dengan mentakrifkan makro "YY_DECL". Sebagai contoh, anda boleh
menggunakan:

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

untuk memberi nama rutin pengimbasan lexscan, mengembalikan pelampung, dan mengambil dua pelampung sebagai
hujah. Ambil perhatian bahawa jika anda memberikan hujah kepada rutin pengimbasan menggunakan gaya K&R/bukan-
pengisytiharan fungsi prototaip, anda mesti menamatkan definisi dengan koma bertindih (;).

Bila-bila masa yylex() dipanggil, ia mengimbas token daripada fail input global yyin (yang
lalai kepada stdin). Ia berterusan sehingga ia sama ada mencapai akhir fail (pada titik mana
ia mengembalikan nilai 0) atau salah satu tindakannya melaksanakan a pulangan kenyataan.

Jika pengimbas mencapai akhir fail, panggilan berikutnya tidak ditentukan melainkan sama ada yyin
dihalakan pada fail input baharu (dalam hal ini pengimbasan diteruskan dari fail tersebut), atau
yyrestart() dipanggil. yyrestart() mengambil satu hujah, a FAIL * penunjuk (yang boleh
tiada, jika anda telah menyediakan YY_INPUT untuk mengimbas daripada sumber selain daripada yyin), dan memulakan
yyin untuk mengimbas daripada fail itu. Pada asasnya tidak ada perbezaan antara adil
menyerahkan yyin ke fail input baharu atau menggunakan yyrestart() untuk berbuat demikian; yang terakhir tersedia
untuk keserasian dengan versi sebelumnya lentur, dan kerana ia boleh digunakan untuk menukar
masukkan fail di tengah-tengah pengimbasan. Ia juga boleh digunakan untuk membuang arus
penimbal input, dengan memanggilnya dengan hujah yyin; tetapi lebih baik digunakan YY_FLUSH_BUFFER
(lihat di atas). Perhatikan bahawa yyrestart() tidak tidak set semula keadaan mula kepada Awal (Lihat
Mulakan Syarat, di bawah).

If yylex() berhenti mengimbas kerana melaksanakan a pulangan kenyataan dalam salah satu tindakan, yang
pengimbas kemudiannya boleh dipanggil semula dan ia akan menyambung semula pengimbasan di tempat ia berhenti.

Secara lalai (dan untuk tujuan kecekapan), pengimbas menggunakan blok-baca dan bukannya
mudah getc() panggilan untuk membaca aksara daripada yyin. Sifat bagaimana ia mendapat inputnya boleh
dikawal dengan mentakrifkan YY_INPUT makro. Urutan panggilan YY_INPUT ialah
"YY_INPUT(buf,hasil,saiz_maks)". Tindakannya adalah untuk meletakkan sehingga max_size watak dalam
susunan aksara penggemar dan kembali dalam pembolehubah integer mengakibatkan sama ada bilangan
aksara dibaca atau YY_NULL pemalar (0 pada sistem Unix) untuk menunjukkan EOF. lalai
YY_INPUT membaca daripada penuding fail global "yyin".

Contoh takrifan YY_INPUT (dalam bahagian takrifan fail input):

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

Takrifan ini akan mengubah pemprosesan input untuk berlaku satu aksara pada satu masa.

Apabila pengimbas menerima petunjuk akhir fail daripada YY_INPUT, ia kemudian menyemak
ywrap() fungsi. Jika ywrap() mengembalikan palsu (sifar), maka diandaikan bahawa fungsi itu
telah pergi ke hadapan dan disediakan yyin untuk menunjuk ke fail input lain, dan pengimbasan diteruskan. Jika
ia mengembalikan benar (bukan sifar), kemudian pengimbas ditamatkan, mengembalikan 0 kepada pemanggilnya. Catatan
bahawa dalam mana-mana kes, keadaan permulaan kekal tidak berubah; ia berlaku tidak kembali kepada AWAL.

Jika anda tidak membekalkan versi anda sendiri yywrap(), maka anda mesti sama ada menggunakan %pilihan
noyywrap (dalam hal ini pengimbas berkelakuan seolah-olah ywrap() dikembalikan 1), atau anda mesti
kaitkan dengan -ll untuk mendapatkan versi lalai rutin, yang sentiasa mengembalikan 1.

Tiga rutin tersedia untuk mengimbas daripada penimbal dalam memori dan bukannya fail:
yy_scan_string(), yy_scan_bait(), and yy_scan_buffer(). Lihat perbincangan mereka di bawah
dalam bahagian Penampan Berbilang Input.

Pengimbas menulisnya ECHO output kepada yyout global (lalai, stdout), yang mungkin
ditakrifkan semula oleh pengguna hanya dengan memberikannya kepada orang lain FAIL penunjuk.

MULA SYARAT


flex menyediakan mekanisme untuk peraturan mengaktifkan bersyarat. Mana-mana peraturan yang coraknya
diawali dengan " " hanya akan aktif apabila pengimbas berada dalam keadaan mula dinamakan
"sc". Sebagai contoh,

[^"]* { /* memakan badan tali ... */
...
}

akan aktif hanya apabila pengimbas berada dalam keadaan mula "STRING", dan

\. { /* kendalikan pelarian ... */
...
}

akan aktif hanya apabila keadaan mula semasa sama ada "INITIAL", "STRING", atau
"PETIK".

Keadaan mula diisytiharkan dalam bahagian definisi (pertama) input menggunakan
garisan tidak bersilang bermula dengan sama ada %s or %x diikuti dengan senarai nama. Yang dahulu
mengisytiharkan inklusif keadaan mula, yang terakhir eksklusif keadaan mula. Satu permulaan
keadaan diaktifkan menggunakan BEGIN tindakan. Sehingga seterusnya BEGIN tindakan dilaksanakan,
peraturan dengan syarat permulaan yang diberikan akan aktif dan peraturan dengan syarat permulaan yang lain
akan tidak aktif. Jika keadaan permulaan ialah termasuk, kemudian memerintah tanpa permulaan
keadaan sama sekali juga akan aktif. Jika ia adalah eksklusif, kemudian hanyalah peraturan yang layak dengan
keadaan permulaan akan aktif. Satu set peraturan bergantung pada permulaan eksklusif yang sama
keadaan menerangkan pengimbas yang bebas daripada mana-mana peraturan lain dalam flex
input. Oleh sebab itu, syarat permulaan eksklusif memudahkan untuk menentukan "mini-
pengimbas" yang mengimbas bahagian input yang berbeza secara sintaksis daripada yang lain
(cth, komen).

Jika perbezaan antara syarat permulaan inklusif dan eksklusif masih sedikit
samar-samar, berikut ialah contoh mudah yang menggambarkan hubungan antara keduanya. Set daripada
peraturan:

%s contoh
%%

foo do_something();

bar something_else();

adalah bersamaan dengan

%x contoh
%%

foo do_something();

bar something_else();

Tanpa kelayakan, yang bar corak dalam contoh kedua tidak akan menjadi
aktif (iaitu, tidak dapat dipadankan) apabila dalam keadaan mula contohnya. Jika kita hanya menggunakan
untuk melayakkan diri bar, walaupun, maka ia hanya akan aktif dalam contoh dan tidak masuk AWAL, manakala
dalam contoh pertama ia aktif dalam kedua-duanya, kerana dalam contoh pertama contoh permulaan
syarat ialah inklusif (%s) keadaan mula.

Juga ambil perhatian bahawa penentu keadaan permulaan khas <*> sepadan dengan setiap keadaan permulaan.
Oleh itu, contoh di atas juga boleh ditulis;

%x contoh
%%

foo do_something();

<*>bar something_else();

Peraturan lalai (kepada ECHO mana-mana watak yang tidak dapat ditandingi) kekal aktif dalam keadaan mula. Ia
bersamaan dengan:

<*>.|\n ECHO;

BEGIN(0) kembali ke keadaan asal di mana hanya peraturan tanpa syarat permulaan
aktif. Keadaan ini juga boleh dirujuk sebagai keadaan permulaan "INITIAL", jadi
BERMULA(MULA) adalah bersamaan dengan BEGIN(0). (Kurungan di sekeliling keadaan mula
nama tidak diperlukan tetapi dianggap gaya yang baik.)

BEGIN tindakan juga boleh diberikan sebagai kod inden pada permulaan bahagian peraturan.
Sebagai contoh, perkara berikut akan menyebabkan pengimbas memasuki keadaan mula "SPECIAL".
apabila yylex() dipanggil dan pembolehubah global masukkan_istimewa betul:

int enter_special;

%x KHAS
%%
jika ( masukkan_istimewa )
BERMULA(KHAS);

blah blah Blah
... lebih banyak peraturan ikut...

Untuk menggambarkan penggunaan keadaan mula, berikut ialah pengimbas yang menyediakan dua berbeza
tafsiran rentetan seperti "123.456". Secara lalai ia akan menganggapnya sebagai tiga token,
integer "123", satu titik ('.'), dan integer "456". Tetapi jika rentetan didahului
lebih awal dalam baris dengan rentetan "jangka-terapung" ia akan menganggapnya sebagai satu token, iaitu
nombor titik terapung 123.456:

%{
#sertakan
%}
%s jangkakan

%%
expect-floats BEGIN(expect);

[0-9]+"."[0-9]+ {
printf("menjumpai pelampung, = %f\n",
atof( yytext ) );
}
\n {
/* itulah penghujung baris, jadi
* kami memerlukan "bilangan jangkaan" lain
* sebelum kita mengenali lagi
* nombor
*/
BERMULA(MULA);
}

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

"." printf("menjumpai titik\n");

Berikut ialah pengimbas yang mengecam (dan membuang) komen C sambil mengekalkan kiraan
baris input semasa.

%x ulasan
%%
int line_num = 1;

"/*" BEGIN(komen);

[^*\n]* /* makan apa sahaja yang bukan '*' */
"*"+[^*/\n]* /* makan '*'s tidak diikuti oleh '/'s */
\n ++line_num;
"*"+"/" MULA(MULA);

Pengimbas ini menghadapi sedikit masalah untuk memadankan sebanyak mungkin teks dengan setiap peraturan.
Secara umum, apabila cuba menulis pengimbas berkelajuan tinggi cuba padankan sebanyak mungkin
setiap peraturan, kerana ia adalah kemenangan besar.

Ambil perhatian bahawa nama keadaan mula adalah benar-benar nilai integer dan boleh disimpan sedemikian.
Oleh itu, perkara di atas boleh dilanjutkan dengan cara berikut:

%x komen foo
%%
int line_num = 1;
int komen_pemanggil;

"/*" {
komen_pemanggil = AWAL;
BEGIN(komen);
}

...

"/*" {
komen_pemanggil = foo;
BEGIN(komen);
}

[^*\n]* /* makan apa sahaja yang bukan '*' */
"*"+[^*/\n]* /* makan '*'s tidak diikuti oleh '/'s */
\n ++line_num;
"*"+"/" BEGIN(comment_caller);

Tambahan pula, anda boleh mengakses keadaan permulaan semasa menggunakan nilai integer YY_START
makro. Sebagai contoh, tugasan di atas untuk komen_pemanggil sebaliknya boleh ditulis

comment_caller = YY_START;

Flex menyediakan YYSTATE sebagai alias untuk YY_START (kerana itulah yang digunakan oleh AT&T lex).

Ambil perhatian bahawa syarat permulaan tidak mempunyai ruang nama mereka sendiri; %s dan %x's mengisytiharkan nama
dengan cara yang sama seperti #define.

Akhir sekali, berikut ialah contoh cara memadankan rentetan petikan gaya C menggunakan permulaan eksklusif
keadaan, termasuk urutan pelarian yang diperluas (tetapi tidak termasuk menyemak rentetan
itu terlalu panjang):

%x str

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

\" string_buf_ptr = string_buf; BEGIN(str);

\" { /* melihat petikan penutup - semua selesai */
BERMULA(MULA);
*string_buf_ptr = '\0';
/* kembalikan rentetan jenis token pemalar dan
* nilai untuk penghurai
*/
}

\n {
/* ralat - pemalar rentetan tidak ditamatkan */
/* jana mesej ralat */
}

\\[0-7]{1,3} {
/* turutan pelarian oktal */
int hasil;

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

jika ( hasil > 0xff )
/* ralat, pemalar di luar batas */

*string_buf_ptr++ = hasil;
}

\\[0-9]+ {
/* menjana ralat - urutan pelarian yang buruk; sesuatu
* seperti '\48' atau '\0777777'
*/
}

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

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

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

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

Selalunya, seperti dalam beberapa contoh di atas, anda akhirnya menulis sekumpulan peraturan
semuanya didahului oleh keadaan mula yang sama. Flex menjadikan ini lebih mudah dan bersih
dengan memperkenalkan tanggapan keadaan mula skop. Skop keadaan permulaan dimulakan dengan:

{

di mana SC ialah senarai satu atau lebih syarat permulaan. Di dalam skop keadaan permulaan,
setiap peraturan secara automatik mempunyai awalan digunakan padanya, sehingga a '}' yang sepadan dengan
awal '{'. Jadi, sebagai contoh,

{
"\\n" kembalikan '\n';
"\\r" kembalikan '\r';
"\\f" kembalikan '\f';
"\\0" kembalikan '\0';
}

bersamaan dengan:

"\\n" kembalikan '\n';
"\\r" kembalikan '\r';
"\\f" kembalikan '\f';
"\\0" kembalikan '\0';

Skop keadaan mula mungkin bersarang.

Tiga rutin tersedia untuk memanipulasi susunan keadaan permulaan:

membatalkan yy_push_state(int new_state)
menolak keadaan permulaan semasa ke atas timbunan keadaan mula dan
beralih ke negeri_baru seolah-olah anda telah menggunakannya BEGIN negeri_baru (ingat permulaan itu
nama keadaan juga adalah integer).

membatalkan yy_pop_state()
muncul bahagian atas tindanan dan beralih kepadanya melalui BERMULA.

int yy_top_state()
mengembalikan bahagian atas tindanan tanpa mengubah kandungan tindanan.

Timbunan keadaan permulaan berkembang secara dinamik dan oleh itu tidak mempunyai had saiz terbina dalam. Jika
ingatan habis, pelaksanaan program dihentikan.

Untuk menggunakan tindanan keadaan mula, pengimbas anda mesti menyertakan a %pilihan timbunan arahan (lihat
Pilihan di bawah).

PELBAGAI INPUT PENAPI


Sesetengah pengimbas (seperti yang menyokong fail "termasuk") memerlukan bacaan daripada beberapa
aliran input. Sebagai flex pengimbas melakukan sejumlah besar penimbal, seseorang tidak dapat mengawal di mana
input seterusnya akan dibaca daripada dengan hanya menulis a YY_INPUT yang sensitif terhadap
konteks pengimbasan. YY_INPUT hanya dipanggil apabila pengimbas mencapai penghujung penimbalnya,
yang mungkin lama selepas mengimbas kenyataan seperti "termasuk" yang memerlukan
menukar sumber input.

Untuk merundingkan masalah seperti ini, flex menyediakan mekanisme untuk mencipta dan menukar
antara berbilang penampan input. Penampan input dibuat dengan menggunakan:

YY_BUFFER_STATE yy_create_buffer( FAIL *fail, saiz int )

yang mengambil a FAIL penunjuk dan saiz dan mencipta penimbal yang dikaitkan dengan fail yang diberikan
dan cukup besar untuk dipegang saiz aksara (apabila ragu-ragu, gunakan YY_BUF_SIZE untuk saiz).
Ia mengembalikan a YY_BUFFER_STATE pemegang, yang kemudiannya boleh dihantar ke rutin lain (lihat
di bawah). The YY_BUFFER_STATE jenis ialah penunjuk kepada legap struktur yy_buffer_state
struktur, jadi anda boleh memulakan pembolehubah YY_BUFFER_STATE dengan selamat ((YY_BUFFER_STATE) 0)
jika anda mahu, dan juga merujuk kepada struktur legap untuk mengisytiharkan input dengan betul
penimbal dalam fail sumber selain daripada pengimbas anda. Perhatikan bahawa FAIL penunjuk dalam
panggilan ke yy_create_buffer hanya digunakan sebagai nilai yyin dilihat oleh YY_INPUT; jika anda
ubah semula YY_INPUT jadi ia tidak lagi digunakan yyin, maka anda boleh melepasi sifar dengan selamat FAIL penunjuk
kepada yy_create_buffer. Anda memilih penimbal tertentu untuk diimbas daripada menggunakan:

batalkan yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )

menukar penimbal input pengimbas supaya token seterusnya akan datang new_buffer. Nota
Bahawa yy_switch_to_buffer() boleh digunakan oleh yywrap() untuk menyediakan perkara untuk diteruskan
mengimbas, bukannya membuka fail baharu dan menunjuk yyin padanya. Perhatikan juga penukaran itu
sumber input melalui sama ada yy_switch_to_buffer() or ywrap() tidak tidak ubah permulaan
keadaan.

batal yy_delete_buffer( YY_BUFFER_STATE buffer )

digunakan untuk menuntut semula storan yang dikaitkan dengan penimbal. ( penampan boleh jadi nil, di mana
kes rutin tidak melakukan apa-apa.) Anda juga boleh mengosongkan kandungan semasa penimbal
menggunakan:

batal yy_flush_buffer( YY_BUFFER_STATE buffer )

Fungsi ini membuang kandungan penimbal, jadi pada kali seterusnya pengimbas cuba melakukannya
memadankan token daripada penimbal, ia akan mengisi penimbal terlebih dahulu dengan menggunakan YY_INPUT.

yy_new_buffer() adalah alias untuk yy_create_buffer(), disediakan untuk keserasian dengan
Penggunaan C++ daripada baru and memadam untuk mencipta dan memusnahkan objek dinamik.

Akhir sekali, YY_CURRENT_BUFFER pulangan makro a YY_BUFFER_STATE mengendalikan kepada arus
buffer.

Berikut ialah contoh menggunakan ciri ini untuk menulis pengimbas yang mengembang termasuk
fail (the < > ciri dibincangkan di bawah):

/* keadaan "termasuk" digunakan untuk mengambil nama
* daripada fail sertakan
*/
%x termasuk

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

%%
sertakan BEGIN(termasuk);

[az]+ ECHO;
[^az\n]*\n? ECHO;

[ \t]* /* makan ruang putih */
[^ \t\n]+ { /* mendapat nama fail sertakan */
jika ( include_stack_ptr >= MAX_INNCLUDE_DEPTH )
{
fprintf( stderr, "Termasuk bersarang terlalu dalam" );
keluar(1);
}

include_stack[include_stack_ptr++] =
YY_CURRENT_BUFFER;

yyin = fopen( yytext, "r" );

jika ( ! yyin )
ralat(...);

yy_switch_to_buffer(
yy_create_buffer( yyin, YY_BUF_SIZE ) );

BERMULA(MULA);
}

< > {
jika ( --include_stack_ptr < 0 )
{
yyterminate();
}

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

Tiga rutin tersedia untuk menyediakan penimbal input untuk mengimbas rentetan dalam memori
bukannya fail. Kesemua mereka mencipta penimbal input baharu untuk mengimbas rentetan, dan
kembalikan yang sepadan YY_BUFFER_STATE pemegang (yang harus anda padamkan dengan
yy_delete_buffer() apabila selesai dengannya). Mereka juga beralih kepada penimbal baharu menggunakan
yy_switch_to_buffer(), jadi panggilan seterusnya ke yylex() akan mula mengimbas rentetan.

yy_scan_string(const tangki *str)
mengimbas rentetan yang ditamatkan NUL.

yy_scan_bait(const tangki *bait, int len)
imbasan len bait (termasuk kemungkinan NUL) bermula di lokasi bait.

Ambil perhatian bahawa kedua-dua fungsi ini mencipta dan mengimbas a salinan daripada rentetan atau bait. (Ini
mungkin wajar, kerana yylex() mengubah suai kandungan penimbal yang sedang diimbas.) Anda
boleh mengelakkan salinan dengan menggunakan:

yy_scan_buffer(char *asas, yy_size_t saiz)
yang mengimbas di tempat penimbal bermula pada asas, yang terdiri daripada saiz bait, yang
dua bait terakhir yang mana kemestian be YY_END_OF_BUFFER_CHAR (ASCII NUL). Dua yang terakhir ini
bait tidak diimbas; oleh itu, pengimbasan terdiri daripada asas[0] melalui asas [saiz-2],
termasuk.

Jika anda gagal untuk menyediakan asas dengan cara ini (iaitu, lupakan dua yang terakhir
YY_END_OF_BUFFER_CHAR bait), kemudian yy_scan_buffer() sebaliknya mengembalikan penunjuk sifar
mencipta penimbal input baharu.

Jenisnya yy_size_t ialah jenis integral yang anda boleh menghantar ungkapan integer
mencerminkan saiz penimbal.

TAMAT FAIL PERATURAN


Peraturan khas "< >" menunjukkan tindakan yang perlu diambil apabila akhir fail
ditemui dan yywrap() mengembalikan bukan sifar (iaitu, menunjukkan tiada fail lagi untuk diproses).
Tindakan itu mesti diselesaikan dengan melakukan salah satu daripada empat perkara:

- menugaskan yyin ke fail input baharu (dalam versi flex sebelumnya, selepas melakukan
tugasan anda terpaksa memanggil tindakan khas YY_NEW_FILE; ini tidak lagi
perlu);

- melaksanakan a pulangan kenyataan;

- melaksanakan khas tamat tempoh () tindakan;

- atau, bertukar kepada penimbal baharu menggunakan yy_switch_to_buffer() seperti yang ditunjukkan dalam contoh
atas.

< > peraturan tidak boleh digunakan dengan corak lain; mereka mungkin hanya layak dengan senarai
keadaan permulaan. Jika < > peraturan diberikan, ia terpakai kepada semua permulaan
syarat yang belum mempunyai < > tindakan. Untuk menentukan < > peraturan untuk sahaja
keadaan permulaan awal, gunakan

< >

Peraturan ini berguna untuk menangkap perkara seperti ulasan tidak tertutup. Satu contoh:

%x petikan
%%

...peraturan lain untuk berurusan dengan sebut harga...

< > {
ralat("sebut harga tidak ditamatkan");
yyterminate();
}
< > {
jika ( *++ senarai fail )
yyin = fopen( *senarai fail, "r" );
lagi
yyterminate();
}

PELBAGAI MAKROS


Makro YY_USER_ACTION boleh ditakrifkan untuk menyediakan tindakan yang sentiasa dilaksanakan
sebelum tindakan peraturan dipadankan. Sebagai contoh, ia boleh #define'd untuk memanggil rutin
untuk menukar yytext kepada huruf kecil. Bila YY_USER_ACTION dipanggil, pembolehubah yy_act
memberikan nombor peraturan yang dipadankan (peraturan dinomborkan bermula dengan 1). Andaikan anda
ingin membuat profil berapa kerap setiap peraturan anda dipadankan. Yang berikut akan melakukan
helah:

#define YY_USER_ACTION ++ctr[yy_act]

di mana ctr ialah tatasusunan untuk menahan kiraan bagi peraturan yang berbeza. Perhatikan bahawa makro
YY_NUM_RULES memberikan jumlah bilangan peraturan (termasuk peraturan lalai, walaupun anda menggunakan
-s), jadi pengisytiharan yang betul untuk ctr ialah:

int ctr[YY_NUM_RULES];

Makro YY_USER_INIT boleh ditakrifkan untuk menyediakan tindakan yang sentiasa dilaksanakan sebelum ini
imbasan pertama (dan sebelum permulaan dalaman pengimbas dilakukan). Sebagai contoh,
ia boleh digunakan untuk memanggil rutin untuk membaca dalam jadual data atau membuka fail pengelogan.

Makro yy_set_interactive(is_interactive) boleh digunakan untuk mengawal sama ada arus
penimbal dipertimbangkan interaktif. Penampan interaktif diproses dengan lebih perlahan, tetapi
mesti digunakan apabila sumber input pengimbas sememangnya interaktif untuk mengelakkan masalah yang timbul
menunggu untuk mengisi penimbal (lihat perbincangan tentang -I bendera di bawah). Nilai bukan sifar dalam
seruan makro menandakan penimbal sebagai interaktif, nilai sifar sebagai tidak interaktif.
Ambil perhatian bahawa penggunaan makro ini mengatasi %pilihan interaktif , %pilihan sentiasa interaktif or
%pilihan tidak pernah interaktif (lihat Pilihan di bawah). yy_set_interactive() mesti dipanggil terlebih dahulu
untuk mula mengimbas penimbal yang (atau tidak) untuk dianggap interaktif.

Makro yy_set_bol(at_bol) boleh digunakan untuk mengawal sama ada pengimbasan penimbal semasa
konteks untuk padanan token seterusnya dilakukan seolah-olah pada permulaan baris. Bukan sifar
hujah makro membuat peraturan berlabuh dengan

Makro YY_AT_BOL() kembali benar jika token seterusnya yang diimbas daripada penimbal semasa akan
mempunyai peraturan '^' aktif, sebaliknya palsu.

Dalam pengimbas yang dijana, semua tindakan dikumpulkan dalam satu pernyataan suis besar dan
diasingkan menggunakan YY_BREAK, yang boleh ditakrifkan semula. Secara lalai, ia hanyalah "rehat", untuk
asingkan setiap tindakan peraturan daripada peraturan berikut. Mentakrif semula YY_BREAK membolehkan, untuk
contoh, pengguna C++ untuk #define YY_BREAK untuk tidak melakukan apa-apa (sambil berhati-hati bahawa setiap
peraturan berakhir dengan "break" atau "return"!) untuk mengelak daripada mengalami kenyataan yang tidak dapat dicapai
amaran di mana kerana tindakan peraturan berakhir dengan "kembali", yang YY_BREAK tidak boleh diakses.

NILAI-NILAI TERSEDIA KEPADA THE PENGGUNA


Bahagian ini meringkaskan pelbagai nilai yang tersedia kepada pengguna dalam tindakan peraturan.

- tangki *yytext memegang teks token semasa. Ia mungkin diubah suai tetapi tidak
dipanjangkan (anda tidak boleh menambah aksara ke penghujung).

Jika arahan khas %array muncul di bahagian pertama pengimbas
penerangan, kemudian yytext sebaliknya diisytiharkan tangki yytext[YYLMAX], di mana YYLMAX ialah
definisi makro yang boleh anda takrifkan semula dalam bahagian pertama jika anda tidak menyukainya
nilai lalai (biasanya 8KB). menggunakan %array menghasilkan pengimbas yang agak perlahan,
tetapi nilai yytext menjadi kebal terhadap panggilan ke input() and unput(), yang
berpotensi memusnahkan nilainya apabila yytext ialah penunjuk watak. Bertentangan dengan
%array is %penunjuk, yang merupakan lalai.

Anda tidak boleh menggunakan %array apabila menjana kelas pengimbas C++ (the -+ bendera).

- int yyleng memegang panjang token semasa.

- FAIL *yyin ialah fail yang secara lalai flex membaca daripada. Ia mungkin ditakrifkan semula tetapi
berbuat demikian hanya masuk akal sebelum pengimbasan bermula atau selepas EOF telah dilakukan
dihadapi. Menukarnya semasa pengimbasan akan mendapat hasil yang tidak dijangka
sejak flex menampan inputnya; guna yyrestart() sebaliknya. Sebaik sahaja pengimbasan ditamatkan
kerana akhir fail telah dilihat, anda boleh menetapkan yyin pada fail input baharu dan
kemudian panggil pengimbas sekali lagi untuk meneruskan pengimbasan.

- membatalkan yyrestart( FAIL *fail_baru ) boleh dipanggil untuk menunjuk yyin pada fail input baharu.
Peralihan kepada fail baharu adalah serta-merta (sebarang input penimbal sebelum ini ialah
hilang). Perhatikan panggilan itu yyrestart() bersama yyin sebagai hujah justeru membuang
penimbal input semasa dan terus mengimbas fail input yang sama.

- FAIL *yyout adalah fail yang ECHO tindakan dilakukan. Ia boleh ditugaskan semula oleh
pengguna.

- YY_CURRENT_BUFFER mengembalikan a YY_BUFFER_STATE mengendalikan ke penimbal semasa.

- YY_START mengembalikan nilai integer yang sepadan dengan keadaan permulaan semasa.
Anda kemudiannya boleh menggunakan nilai ini dengan BEGIN untuk kembali ke keadaan permulaan itu.

ANTARA MUKA DENGAN YACC


Salah satu kegunaan utama flex adalah sebagai peneman kepada yacc penjana parser. yacc penghurai
mengharapkan untuk memanggil rutin bernama yylex() untuk mencari token input seterusnya. Rutinnya ialah
sepatutnya mengembalikan jenis token seterusnya serta meletakkan sebarang nilai yang berkaitan
global yylval. Untuk menggunakan flex bersama yacc, satu menentukan -d pilihan untuk yacc untuk memberi arahan
ia untuk menjana fail y.tab.h mengandungi definisi semua %token muncul dalam
yacc input. Fail ini kemudiannya dimasukkan ke dalam flex pengimbas. Sebagai contoh, jika salah satu daripada
token ialah "TOK_NUMBER", sebahagian daripada pengimbas mungkin kelihatan seperti:

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

%%

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

PILIHAN


flex mempunyai pilihan berikut:

-b, --sandaran
Hasilkan maklumat sandaran kepada lex.backup. Ini ialah senarai keadaan pengimbas
yang memerlukan sandaran dan aksara input yang mana mereka berbuat demikian. Dengan menambah
peraturan seseorang boleh mengalih keluar keadaan sandaran. Jika semua negeri sandaran dihapuskan
and -Cf or -CF digunakan, pengimbas yang dihasilkan akan berjalan lebih pantas (lihat bahagian -p bendera).
Hanya pengguna yang ingin memerah setiap kitaran terakhir daripada pengimbas mereka perlu bimbang
tentang pilihan ini. (Lihat bahagian tentang Pertimbangan Prestasi di bawah.)

-c ialah pilihan yang tidak berbuat apa-apa, ditamatkan disertakan untuk pematuhan POSIX.

-d, --nyahpepijat
menjadikan pengimbas yang dihasilkan berjalan masuk debug mod. Setiap kali corak dikenali
dan global yy_flex_debug bukan sifar (iaitu lalai), pengimbas akan
tulis kepada stderr satu baris bentuk:

--menerima peraturan pada baris 53 ("teks yang dipadankan")

Nombor baris merujuk kepada lokasi peraturan dalam fail yang menentukan pengimbas
(iaitu, fail yang disuakan untuk melenturkan). Mesej juga dijana apabila
pengimbas membuat sandaran, menerima peraturan lalai, mencapai penghujung penimbal inputnya (atau
menemui NUL; pada ketika ini, kedua-duanya kelihatan sama sejauh pengimbas
berkenaan), atau mencapai akhir fail.

-f, --penuh
menyatakan cepat pengimbas. Tiada pemampatan jadual dilakukan dan stdio dipintas. The
hasilnya besar tetapi cepat. Pilihan ini bersamaan dengan -Cfr (lihat di bawah).

-h, - membantu
menjana ringkasan "bantuan" bagi flex's pilihan untuk stdout dan kemudian keluar. -? and
- membantu adalah sinonim untuk -h.

-saya, --tidak peka huruf besar-besaran
memberi arahan flex untuk menjana a kes sensitif pengimbas. Kes surat yang diberi
dalam flex corak input akan diabaikan, dan token dalam input akan dipadankan
tanpa mengira kes. Teks yang dipadankan diberikan dalam yytext akan mempunyai kes yang dipelihara
(iaitu, ia tidak akan dilipat).

-l, --lex-compat
menghidupkan keserasian maksimum dengan AT&T asal lex pelaksanaan. Nota
bahawa ini tidak bermakna penuh keserasian. Penggunaan opsyen ini kos a
jumlah prestasi yang besar, dan ia tidak boleh digunakan dengan -+, -f, -F, -Cf,
or -CF pilihan. Untuk butiran tentang keserasian yang disediakan, lihat bahagian
"Ketidakserasian Dengan Lex Dan POSIX" di bawah. Pilihan ini juga menghasilkan nama
YY_FLEX_LEX_COMPAT sedang #define'd dalam pengimbas yang dijana.

-n ialah satu lagi pilihan yang tidak boleh dilakukan dan tidak digunakan hanya disertakan untuk pematuhan POSIX.

-p, --perf-report
menjana laporan prestasi kepada stderr. Laporan itu terdiri daripada ulasan
mengenai ciri-ciri flex fail input yang akan menyebabkan kehilangan serius
prestasi dalam pengimbas yang terhasil. Jika anda memberikan bendera dua kali, anda juga akan
dapatkan ulasan mengenai ciri yang membawa kepada kehilangan prestasi kecil.

Perhatikan bahawa penggunaan TOLAK, %pilihan yylineno, dan konteks belakang berubah-ubah (lihat
bahagian Kekurangan / Pepijat di bawah) memerlukan penalti prestasi yang besar;
penggunaan yymore(), yang ^ pengendali, dan -I bendera memerlukan prestasi kecil
hukuman.

-ya, --tiada-lalai
menyebabkannya lalai memerintah (input pengimbas yang tidak sepadan itu digemakan stdout) menjadi
ditindas. Jika pengimbas menemui input yang tidak sepadan dengan mana-mana peraturannya,
ia membatalkan dengan ralat. Pilihan ini berguna untuk mencari lubang pada pengimbas
set peraturan.

-t, --stdout
memberi arahan flex untuk menulis pengimbas yang dihasilkannya kepada output standard dan bukannya
lex.yy.c.

-v, --verbose
menyatakan bahawa flex harus menulis kepada stderr ringkasan statistik mengenai
pengimbas yang dihasilkannya. Kebanyakan statistik tidak bermakna kepada yang kasual flex
pengguna, tetapi baris pertama mengenal pasti versi flex (sama seperti yang dilaporkan oleh -V),
dan baris seterusnya bendera yang digunakan semasa menjana pengimbas, termasuk yang
dihidupkan secara lalai.

-w, --nowarn
menyekat mesej amaran.

-B, --batch
memberi arahan flex untuk menjana a kumpulan pengimbas, bertentangan dengan interaktif pengimbas
dijana oleh -I (lihat di bawah). Secara umum, anda gunakan -B apabila anda berada tertentu bahawa anda
pengimbas tidak akan digunakan secara interaktif, dan anda ingin memerah a sedikit lebih
prestasi daripadanya. Jika matlamat anda adalah untuk memerah a banyak lebih
prestasi, anda sepatutnya menggunakan -Cf or -CF pilihan (dibincangkan di bawah), yang
hidupkan -B secara automatik pula.

-F, --cepat
menyatakan bahawa cepat perwakilan jadual pengimbas harus digunakan (dan stdio
dipintas). Perwakilan ini adalah lebih kurang sepantas perwakilan jadual penuh
(-f), dan untuk beberapa set corak akan menjadi lebih kecil (dan untuk yang lain,
lebih besar). Secara umum, jika set corak mengandungi kedua-dua "kata kunci" dan catch-all,
peraturan "pengecam", seperti dalam set:

"kes" kembalikan TOK_CASE;
"suis" kembalikan TOK_SWITCH;
...
"lalai" kembalikan TOK_DEFAULT;
[az]+ kembalikan TOK_ID;

maka lebih baik anda menggunakan perwakilan jadual penuh. Jika hanya
Peraturan "pengecam" ada dan anda kemudian menggunakan jadual cincang atau beberapa seumpamanya untuk mengesan
kata kunci, lebih baik anda gunakan -F.

Pilihan ini bersamaan dengan -CFr (lihat di bawah). Ia tidak boleh digunakan dengan -+.

-saya, --interaktif
memberi arahan flex untuk menjana sebuah interaktif pengimbas. Pengimbas interaktif adalah satu
yang hanya melihat ke hadapan untuk memutuskan token yang telah dipadankan jika ia benar-benar mesti.
Ternyata sentiasa melihat satu watak tambahan di hadapan, walaupun pengimbas mempunyai
sudah melihat teks yang mencukupi untuk menyahkekaburan token semasa, adalah lebih pantas daripada
hanya memandang ke hadapan apabila perlu. Tetapi pengimbas yang sentiasa melihat ke hadapan memberi
prestasi interaktif yang mengerikan; sebagai contoh, apabila pengguna menaip baris baharu, ia adalah
tidak diiktiraf sebagai token baris baharu sehingga mereka masuk lain token, yang selalunya bermaksud
menaip dalam baris keseluruhan yang lain.

Flex pengimbas lalai kepada interaktif melainkan anda menggunakan -Cf or -CF meja-
pilihan mampatan (lihat di bawah). Itu kerana jika anda mencari yang tinggi-
prestasi anda sepatutnya menggunakan salah satu daripada pilihan ini, jadi jika anda tidak melakukannya, flex
menganggap anda lebih suka menukar sedikit prestasi masa jalan untuk intuitif
tingkah laku interaktif. Perhatikan juga bahawa anda tidak boleh penggunaan -I bersempena dengan -Cf or
-CF. Oleh itu, pilihan ini tidak benar-benar diperlukan; ia dihidupkan secara lalai untuk semua itu
kes di mana ia dibenarkan.

Perhatikan bahawa jika isatty () mengembalikan palsu untuk input pengimbas, flex akan kembali ke
mod kelompok, walaupun -I telah dinyatakan. Untuk memaksa mod interaktif tidak kira apa pun,
penggunaan %pilihan sentiasa interaktif (lihat Pilihan di bawah).

Anda boleh memaksa pengimbas untuk tidak menjadi interaktif dengan menggunakan -B (lihat di atas).

-L, --noline
memberi arahan flex bukan untuk menjana #garisan arahan. Tanpa pilihan ini, flex lada
pengimbas yang dijana dengan arahan #baris supaya mesej ralat dalam tindakan akan
diletakkan dengan betul berkenaan dengan sama ada yang asal flex fail input (jika
ralat disebabkan oleh kod dalam fail input), atau lex.yy.c (jika ralatnya flex's
kesalahan -- anda harus melaporkan jenis ralat ini ke alamat e-mel yang diberikan di bawah).

-T, --jejak
membuat flex berjalan masuk mengesan mod. Ia akan menjana banyak mesej kepada stderr
berkenaan bentuk input dan hasil bukan deterministik dan
automata terhingga deterministik. Pilihan ini kebanyakannya untuk digunakan dalam penyelenggaraan lentur.

-V, --versi
mencetak nombor versi ke stdout dan keluar. --versi adalah sinonim untuk -V.

-7, --7bit
memberi arahan flex untuk menjana pengimbas 7-bit, iaitu, yang hanya boleh mengecam
aksara 7-bit dalam inputnya. Kelebihan menggunakan -7 adakah itu pengimbas
jadual boleh sehingga separuh saiz yang dijana menggunakan -8 pilihan (lihat
di bawah). Kelemahannya ialah pengimbas sedemikian sering menggantung atau ranap jika inputnya
mengandungi aksara 8-bit.

Walau bagaimanapun, ambil perhatian bahawa melainkan anda menjana pengimbas anda menggunakan -Cf or -CF meja
pilihan mampatan, penggunaan -7 akan menjimatkan hanya sedikit ruang meja, dan
jadikan pengimbas anda kurang mudah alih. Flex's tingkah laku lalai adalah untuk
menjana pengimbas 8-bit melainkan anda menggunakan -Cf or -CF, dalam kes mana flex
lalai untuk menjana pengimbas 7-bit melainkan tapak anda sentiasa dikonfigurasikan untuk
menjana pengimbas 8-bit (seperti yang selalunya berlaku dengan tapak bukan AS). Awak boleh
beritahu sama ada flex menjana pengimbas 7-bit atau 8-bit dengan memeriksa bendera
ringkasan dalam -v output seperti yang diterangkan di atas.

Perhatikan bahawa jika anda menggunakan -Cfe or -CFe (pilihan pemampatan jadual tersebut, tetapi juga menggunakan
kelas kesetaraan seperti yang dibincangkan lihat di bawah), flex masih lalai untuk menjana an
Pengimbas 8-bit, kerana biasanya dengan pilihan mampatan ini jadual 8-bit penuh adalah
tidak lebih mahal daripada jadual 7-bit.

-8, --8bit
memberi arahan flex untuk menjana pengimbas 8-bit, iaitu, yang boleh mengenali 8-bit
watak. Bendera ini hanya diperlukan untuk pengimbas yang dihasilkan menggunakan -Cf or -CF, as
sebaliknya flex lalai untuk menjana pengimbas 8-bit pula.

Lihat perbincangan mengenai -7 di atas untuk tingkah laku lalai flex dan pertukaran
antara pengimbas 7-bit dan 8-bit.

-+, --c++
menentukan bahawa anda mahu fleksibel untuk menjana kelas pengimbas C++. Lihat bahagian pada
Menjana Pengimbas C++ di bawah untuk butiran.

-C[aefFmr]
mengawal tahap pemampatan meja dan, lebih amnya, pertukaran antara
pengimbas kecil dan pengimbas pantas.

-Ca, --selaraskan ("menjajarkan") mengarahkan flex untuk menukar jadual yang lebih besar dalam yang dihasilkan
pengimbas untuk prestasi yang lebih pantas kerana elemen jadual adalah lebih baik
diselaraskan untuk akses memori dan pengiraan. Pada beberapa seni bina RISC, mengambil
dan memanipulasi kata panjang adalah lebih cekap berbanding dengan unit bersaiz lebih kecil seperti
kata pendek. Pilihan ini boleh menggandakan saiz jadual yang digunakan oleh pengimbas anda.

-Ce, --ecs mengarahkan flex untuk membina kesetaraan kelas, iaitu set watak
yang mempunyai sifat leksikal yang sama (contohnya, jika satu-satunya penampilan
digit dalam flex input berada dalam kelas aksara "[0-9]" kemudian digit '0',
'1', ..., '9' semuanya akan dimasukkan ke dalam kelas kesetaraan yang sama). Kelas kesetaraan
biasanya memberikan pengurangan dramatik dalam saiz fail jadual/objek akhir (biasanya a
faktor 2-5) dan agak murah dari segi prestasi (satu carian tatasusunan setiap
aksara diimbas).

-Cf menyatakan bahawa penuh jadual pengimbas harus dihasilkan - flex tidak patut
mampatkan jadual dengan memanfaatkan fungsi peralihan yang serupa untuk
negeri yang berbeza.

-CF menyatakan bahawa perwakilan pengimbas pantas alternatif (diterangkan di atas
di bawah -F bendera) hendaklah digunakan. Pilihan ini tidak boleh digunakan dengan -+.

-Cm, --meta-ecs mengarahkan flex untuk membina kesetaraan meta kelas, iaitu set
kelas kesetaraan (atau aksara, jika kelas kesetaraan tidak digunakan)
yang biasa digunakan bersama. Kelas kesetaraan meta selalunya merupakan kemenangan besar apabila
menggunakan jadual termampat, tetapi ia mempunyai kesan prestasi yang sederhana (satu atau dua
ujian "jika" dan satu carian tatasusunan bagi setiap aksara yang diimbas).

-Cr, --baca menyebabkan pengimbas yang dihasilkan memintas penggunaan perpustakaan I/O standard
(stdio) untuk input. Daripada menelefon fread() or getc(), pengimbas akan menggunakan
baca () panggilan sistem, menghasilkan keuntungan prestasi yang berbeza dari sistem ke
sistem, tetapi secara amnya mungkin boleh diabaikan melainkan anda juga menggunakan -Cf or -CF.
Menggunakan -Cr boleh menyebabkan tingkah laku pelik jika, sebagai contoh, anda membaca daripada yyin menggunakan
stdio sebelum memanggil pengimbas (kerana pengimbas akan terlepas apa-apa teks
bacaan anda sebelum ini ditinggalkan dalam penimbal input stdio).

-Cr tidak mempunyai kesan jika anda mentakrifkan YY_INPUT (lihat Pengimbas Dijana di atas).

Satu kesendirian -C menentukan bahawa jadual pengimbas harus dimampatkan tetapi tidak
kelas kesetaraan mahupun kelas kesetaraan meta harus digunakan.

Pilihannya -Cf or -CF and -Cm tidak masuk akal bersama - tidak ada peluang
untuk kelas kesetaraan meta jika jadual tidak dimampatkan. Jika tidak
pilihan mungkin bercampur bebas, dan terkumpul.

Tetapan lalai adalah -Cem, yang menyatakan itu flex harus menjana kesetaraan
kelas dan kelas kesetaraan meta. Tetapan ini menyediakan tahap tertinggi
pemampatan meja. Anda boleh menukar pengimbas yang melaksanakan lebih pantas dengan kos
jadual yang lebih besar dengan yang berikut secara amnya adalah benar:

paling perlahan & paling kecil
-Cem
-Cm
-Ce
-C
-C{f,F}e
-C{f,F}
-C{f,F}a
terpantas & terbesar

Ambil perhatian bahawa pengimbas dengan jadual terkecil biasanya dijana dan disusun
paling cepat, jadi semasa pembangunan anda biasanya mahu menggunakan lalai, maksimum
mampatan.

-Cfe selalunya merupakan kompromi yang baik antara kelajuan dan saiz untuk pengimbas pengeluaran.

-output, --outputfile=FAIL
mengarahkan flex untuk menulis pengimbas pada fail output bukan lex.yy.c. Jika anda
menggabungkan -o dengan -t pilihan, maka pengimbas ditulis ke stdout tetapi yang #garisan
arahan (lihat -L pilihan di atas) rujuk fail output.

-Awalan, --prefix=STRING
menukar lalai yy awalan yang digunakan oleh flex untuk semua pembolehubah yang boleh dilihat secara global dan
nama fungsi menjadi awalan. Sebagai contoh, -Pfoo menukar nama yytext
kepada teks kaki. Ia juga menukar nama fail output lalai daripada lex.yy.c kepada
lex.foo.c. Berikut adalah semua nama yang terlibat:

yy_create_buffer
yy_delete_buffer
yy_flex_debug
yy_init_buffer
yy_flush_buffer
yy_load_buffer_state
yy_tukar_ke_penampan
yyin
yyleng
yylex
yylineno
yyout
yyrestart
yytext
ywrap

(Jika anda menggunakan pengimbas C++, maka hanya ywrap and yyFlexLexer terjejas.)
Dalam pengimbas anda sendiri, anda masih boleh merujuk kepada pembolehubah global dan
fungsi menggunakan salah satu versi nama mereka; tetapi secara luaran, mereka mempunyai
nama yang diubah suai.

Pilihan ini membolehkan anda memautkan bersama berbilang dengan mudah flex program ke dalam yang sama
boleh dilaksanakan. Walau bagaimanapun, ambil perhatian bahawa menggunakan pilihan ini juga menamakan semula yywrap(), jadi awak sekarang
kemestian sama ada menyediakan versi rutin anda sendiri (dengan nama yang sesuai) untuk anda
pengimbas, atau penggunaan %pilihan noyywrap, sebagai menghubungkan dengan -ll tidak lagi menyediakan satu untuk
anda secara lalai.

-Skeleton_file, --skel=FAIL
mengatasi fail rangka lalai dari mana flex membina pengimbasnya.
Anda tidak akan memerlukan pilihan ini melainkan anda melakukannya flex penyelenggaraan atau pembangunan.

-X, --posix-compat
keserasian maksimum dengan POSIX lex.

--yylineno
kiraan baris trek dalam yylineno.

--yyclass=NAME
nama kelas C++.

--header-file=FAIL
buat fail pengepala C sebagai tambahan kepada pengimbas.

--tables-file[=FILE]
tulis jadual ke FILE.

-Dmakro[=defn]
#define makro defn (default defn ialah '1').

-R, --reentrant
menjana pengimbas C reentrant

--jambatan bison
pengimbas untuk parser tulen bison.

--lokasi-bison
sertakan sokongan yylloc.

--stdinit
mulakan yyin/yyout kepada stdin/stdout.

--noansi-takrifan gaya lama fungsi takrifan.

--noansi-prototaip
senarai parameter kosong dalam prototaip.

--nounistd
jangan masukkan .

--tiada FUNGSI
tidak menjana FUNGSI tertentu.

flex juga menyediakan mekanisme untuk mengawal pilihan dalam spesifikasi pengimbas
itu sendiri, bukannya daripada baris arahan flex. Ini dilakukan dengan memasukkan %pilihan
arahan dalam bahagian pertama spesifikasi pengimbas. Anda boleh menentukan berbilang
pilihan dengan satu %pilihan arahan, dan berbilang arahan dalam bahagian pertama
fail input fleksibel anda.

Kebanyakan pilihan diberikan hanya sebagai nama, secara pilihan didahului dengan perkataan "tidak" (dengan no
intervening whitespace) untuk menafikan maksudnya. Nombor adalah bersamaan dengan bendera flex atau
penafian mereka:

Pilihan 7bit -7
Pilihan 8bit -8
menyelaraskan -Ca pilihan
pilihan sandaran -b
pilihan kumpulan -B
c++ -+ pilihan

caseful atau
berlawanan sensitif huruf besar-besaran daripada -i (lalai)

huruf kecil atau
pilihan -i tanpa kes

pilihan debug -d
lalai bertentangan dengan pilihan -s
ecs -Ce pilihan
pilihan -F cepat
pilihan -f penuh
pilihan -I interaktif
pilihan lex-compat -l
pilihan meta-ecs -Cm
pilihan perf-report -p
baca -Cr pilihan
pilihan stdout -t
verbose -v pilihan
memberi amaran bertentangan dengan pilihan -w
(gunakan "%option nowarn" untuk -w)

tatasusunan bersamaan dengan "%array"
penunjuk bersamaan dengan "%penunjuk" (lalai)

Sesetengah %pilihan menyediakan ciri yang sebaliknya tidak tersedia:

sentiasa interaktif
mengarahkan flex untuk menjana pengimbas yang sentiasa mempertimbangkan inputnya
"interaktif". Biasanya, pada setiap fail input baharu pengimbas memanggil isatty () dalam
cuba untuk menentukan sama ada sumber input pengimbas adalah interaktif dan dengan itu
hendaklah dibaca satu persatu watak. Apabila pilihan ini digunakan, bagaimanapun, maka tidak
panggilan sedemikian dibuat.

utama mengarahkan flex untuk menyediakan lalai main () program untuk pengimbas, yang hanya
panggilan yylex(). Pilihan ini membayangkan noyywrap (lihat di bawah).

tidak pernah interaktif
mengarahkan flex untuk menghasilkan pengimbas yang tidak pernah menganggap inputnya "interaktif"
(sekali lagi, tiada panggilan dibuat ke isatty()). Ini adalah bertentangan dengan sentiasa interaktif.

timbunan membolehkan penggunaan tindanan keadaan mula (lihat Syarat Mula di atas).

stdinit
jika ditetapkan (iaitu, %pilihan stdinit) memulakan yyin and yyout kepada stdin and tekun,
bukannya lalai daripada tiada. Beberapa sedia ada lex program bergantung pada tingkah laku ini,
walaupun ia tidak mematuhi ANSI C, yang tidak memerlukan stdin and
stdout menjadi pemalar masa penyusunan.

yylineno
mengarahkan flex untuk menjana pengimbas yang mengekalkan nombor talian semasa
dibaca daripada inputnya dalam pembolehubah global yylineno. Pilihan ini tersirat oleh
%pilihan lex-compat.

ywrap jika tidak ditetapkan (iaitu, %pilihan noyywrap), membuat pengimbas tidak memanggil ywrap() pada penghujung-
of-file, tetapi hanya menganggap bahawa tiada lagi fail untuk diimbas (sehingga pengguna
mata yyin pada fail dan panggilan baharu yylex() lagi).

flex mengimbas tindakan peraturan anda untuk menentukan sama ada anda menggunakan REJEK or yymore() ciri-ciri.
. menolak and yymore pilihan tersedia untuk mengatasi keputusannya sama ada anda menggunakan
pilihan, sama ada dengan menetapkannya (cth, %pilihan menolak) untuk menunjukkan ciri tersebut adalah
memang digunakan, atau menyahsetkannya untuk menunjukkan ia sebenarnya tidak digunakan (cth, %pilihan
noyymore).

Tiga pilihan mengambil nilai yang dibatasi rentetan, diimbangi dengan '=':

%option outfile="ABC"

adalah bersamaan dengan -oABC, and

%option prefix="XYZ"

adalah bersamaan dengan -PXYZ. Akhirnya,

%option yyclass="foo"

hanya terpakai apabila menjana pengimbas C++ ( -+ pilihan). Ia memaklumkan flex yang awak ada
diperolehi foo sebagai subkelas daripada yyFlexLexer, so flex akan meletakkan tindakan anda dalam ahli
fungsi foo::yylex() bukan yyFlexLexer::yylex(). Ia juga menjana a
yyFlexLexer::yylex() fungsi ahli yang mengeluarkan ralat masa jalan (dengan menggunakan
yyFlexLexer::LexerError()) jika dipanggil. Lihat Menjana Pengimbas C++, di bawah, untuk tambahan
maklumat.

Beberapa pilihan tersedia untuk penulen lin yang ingin menyekat penampilan
rutin yang tidak diperlukan dalam pengimbas yang dihasilkan. Setiap yang berikut, jika tidak ditetapkan (cth,
%pilihan kata nama ), mengakibatkan rutin yang sepadan tidak muncul dalam yang dihasilkan
pengimbas:

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

(walaupun yy_push_state() dan rakan tidak akan muncul melainkan anda menggunakannya %pilihan timbunan).

PRESTASI KONSIDERASI


Matlamat reka bentuk utama flex ialah ia menjana pengimbas berprestasi tinggi. Ia telah
dioptimumkan untuk berurusan dengan baik dengan set peraturan yang besar. Selain daripada kesan pada pengimbas
kelajuan pemampatan meja -C pilihan yang digariskan di atas, terdapat beberapa
pilihan/tindakan yang merendahkan prestasi. Ini adalah, dari yang paling mahal hingga yang paling murah:

REJEK
%pilihan yylineno
konteks ketinggalan sewenang-wenangnya

set corak yang memerlukan sandaran
%array
%opsyen interaktif
%pilihan sentiasa interaktif

'^' operator permulaan talian
yymore()

dengan tiga yang pertama semuanya agak mahal dan dua yang terakhir agak murah. Nota
juga itu unput() dilaksanakan sebagai panggilan rutin yang berpotensi melakukan sedikit sebanyak
bekerja, sambil yyless() adalah makro yang agak murah; jadi jika hanya meletakkan semula lebihan teks anda
diimbas, gunakan yyless().

REJEK harus dielakkan pada semua kos apabila prestasi adalah penting. Ia adalah khususnya
pilihan mahal.

Menghapuskan sandaran adalah berantakan dan selalunya mungkin merupakan jumlah kerja yang besar untuk a
pengimbas yang rumit. Pada prinsipnya, seseorang bermula dengan menggunakan -b bendera untuk menjana a
lex.backup fail. Sebagai contoh, pada input

%%
foo kembalikan TOK_KEYWORD;
foobar kembalikan TOK_KEYWORD;

fail kelihatan seperti:

Negeri #6 tidak menerima -
nombor baris peraturan yang berkaitan:
2 3
peralihan keluar: [ o ]
peralihan jem: EOF [ \001-n p-\177 ]

Negeri #8 tidak menerima -
nombor baris peraturan yang berkaitan:
3
peralihan keluar: [ a ]
peralihan jem: EOF [ \001-` b-\177 ]

Negeri #9 tidak menerima -
nombor baris peraturan yang berkaitan:
3
peralihan keluar: [ r ]
peralihan jem: EOF [ \001-q s-\177 ]

Jadual mampat sentiasa disandarkan.

Beberapa baris pertama memberitahu kami bahawa terdapat keadaan pengimbas di mana ia boleh membuat peralihan
pada 'o' tetapi bukan pada mana-mana aksara lain, dan dalam keadaan itu yang sedang diimbas
teks tidak sepadan dengan mana-mana peraturan. Keadaan berlaku apabila cuba memadankan peraturan yang terdapat di
baris 2 dan 3 dalam fail input. Jika pengimbas berada dalam keadaan itu dan kemudian membaca sesuatu
selain daripada 'o', ia perlu membuat sandaran untuk mencari peraturan yang dipadankan. Dengan sedikit
menggaru kepala seseorang dapat melihat bahawa ini mestilah keadaannya apabila ia telah melihat "fo".
Apabila ini telah berlaku, jika apa-apa selain 'o' lain dilihat, pengimbas akan mempunyai
untuk membuat sandaran untuk hanya memadankan 'f' (mengikut peraturan lalai).

Komen berkenaan Negeri #8 menunjukkan terdapat masalah apabila "foob" telah diimbas.
Malah, pada mana-mana watak selain daripada 'a', pengimbas perlu membuat sandaran untuk menerima
"foo". Begitu juga, ulasan untuk Negeri #9 membimbangkan apabila "fooba" telah diimbas dan a
'r' tidak mengikut.

Komen terakhir mengingatkan kita bahawa tidak ada gunanya menghadapi semua masalah untuk mengalih keluar
membuat sandaran daripada peraturan melainkan kami menggunakan -Cf or -CF, kerana tiada peningkatan prestasi
berbuat demikian dengan pengimbas termampat.

Cara untuk mengalih keluar sandaran adalah dengan menambah peraturan "ralat":

%%
foo kembalikan TOK_KEYWORD;
foobar kembalikan TOK_KEYWORD;

fooba |
bodoh |
untuk {
/* penggera palsu, bukan kata kunci sebenarnya */
kembalikan TOK_ID;
}

Menghapuskan sandaran antara senarai kata kunci juga boleh dilakukan menggunakan peraturan "catch-all":

%%
foo kembalikan TOK_KEYWORD;
foobar kembalikan TOK_KEYWORD;

[az]+ kembalikan TOK_ID;

Ini biasanya penyelesaian terbaik apabila sesuai.

Menyandarkan mesej cenderung untuk berperingkat. Dengan set peraturan yang rumit, ia bukan perkara biasa
dapatkan ratusan mesej. Sekiranya seseorang dapat menguraikannya, ia selalunya hanya memerlukan sedozen
atau lebih peraturan untuk menghapuskan sandaran (walaupun mudah untuk membuat kesilapan dan mempunyai
peraturan ralat secara tidak sengaja sepadan dengan token yang sah. Masa depan yang mungkin flex ciri akan menjadi
menambah peraturan secara automatik untuk menghapuskan sandaran).

Adalah penting untuk diingat bahawa anda mendapat faedah daripada menghapuskan sandaran sahaja
jika anda menghapuskan setiap contoh sandaran. Meninggalkan hanya satu bermakna anda tidak mendapat apa-apa.

Pembolehubah konteks mengekor (di mana kedua-dua bahagian hadapan dan mengekor tidak mempunyai sambungan tetap
panjang) melibatkan kehilangan prestasi yang hampir sama seperti REJEK (iaitu, besar). Jadi bila
mungkin peraturan seperti:

%%
tikus|tikus/(kucing|anjing) lari();

lebih baik ditulis:

%%
tikus/kucing|lari anjing();
tikus/kucing|lari anjing();

atau sebagai

%%
tikus|rat/kucing lari();
tikus|rat/anjing lari();

Ambil perhatian bahawa di sini '|' khas tindakan tidak tidak menyediakan apa-apa simpanan, dan juga boleh membuat
perkara yang lebih teruk (lihat Kekurangan / Pepijat di bawah).

Satu lagi kawasan di mana pengguna boleh meningkatkan prestasi pengimbas (dan yang lebih mudah untuk
implement) timbul daripada fakta bahawa semakin lama token dipadankan, semakin cepat pengimbas
akan lari. Ini kerana dengan token panjang pemprosesan kebanyakan aksara input diperlukan
letakkan dalam gelung pengimbasan dalaman (pendek), dan tidak selalunya perlu melalui
kerja tambahan untuk menyediakan persekitaran pengimbasan (cth, yytext) untuk tindakan tersebut.
Ingat pengimbas untuk ulasan C:

%x ulasan
%%
int line_num = 1;

"/*" BEGIN(komen);

[^*\n]*
"*"+[^*/\n]*
\n ++line_num;
"*"+"/" MULA(MULA);

Ini boleh dipercepatkan dengan menulisnya sebagai:

%x ulasan
%%
int line_num = 1;

"/*" BEGIN(komen);

[^*\n]*
[^*\n]*\n ++line_num;
"*"+[^*/\n]*
"*"+[^*/\n]*\n ++line_num;
"*"+"/" MULA(MULA);

Sekarang bukannya setiap baris baharu memerlukan pemprosesan tindakan lain, mengiktiraf
baris baharu "diedarkan" ke atas peraturan lain untuk mengekalkan teks yang dipadankan selagi
mungkin. Perhatikan bahawa menambah peraturan tidak tidak perlahankan pengimbas! Kelajuan
pengimbas adalah bebas daripada bilangan peraturan atau (modul pertimbangan yang diberikan di
permulaan bahagian ini) betapa rumitnya peraturan berkenaan dengan pengendali seperti
'*' dan '|'.

Contoh terakhir dalam mempercepatkan pengimbas: katakan anda ingin mengimbas melalui fail
mengandungi pengecam dan kata kunci, satu setiap baris dan tanpa aksara luar lain,
dan mengenali semua kata kunci. Pendekatan pertama yang semula jadi ialah:

%%
asm |
auto |
rehat |
... dan lain-lain ...
tidak menentu |
manakala /* ia adalah kata kunci */

.|\n /* itu bukan kata kunci */

Untuk menghapuskan penjejakan belakang, perkenalkan peraturan tangkap semua:

%%
asm |
auto |
rehat |
... dan lain-lain ...
tidak menentu |
manakala /* ia adalah kata kunci */

[az]+ |
.|\n /* itu bukan kata kunci */

Sekarang, jika ia dijamin bahawa terdapat tepat satu perkataan setiap baris, maka kita boleh mengurangkan
jumlah bilangan perlawanan sebanyak setengah dengan menggabungkan dalam pengiktirafan barisan baharu dengan
token yang lain:

%%
asm\n |
auto\n |
rehat\n |
... dan lain-lain ...
tidak menentu\n |
manakala\n /* ia adalah kata kunci */

[az]+\n |
.|\n /* itu bukan kata kunci */

Seseorang perlu berhati-hati di sini, kerana kami kini telah memperkenalkan semula sandaran ke dalam pengimbas. Dalam
khususnya, manakala we ketahui bahawa tidak akan ada sebarang aksara dalam aliran input
selain daripada surat atau baris baharu, flex tidak dapat memikirkan perkara ini, dan ia akan merancang untuk kemungkinannya
perlu membuat sandaran apabila ia telah mengimbas token seperti "auto" dan kemudian watak seterusnya ialah
sesuatu selain daripada baris baharu atau surat. Sebelum ini ia hanya akan sepadan dengan
peraturan "auto" dan selesai, tetapi kini ia tidak mempunyai peraturan "auto", hanya peraturan "auto\n". Kepada
menghapuskan kemungkinan membuat sandaran, kita boleh sama ada menduplikasi semua peraturan tetapi tanpa
baris baharu akhir, atau, kerana kami tidak pernah menjangkakan akan menemui input sedemikian dan oleh itu tidak
bagaimana ia diklasifikasikan, kita boleh memperkenalkan satu lagi peraturan catch-all, yang ini tidak
sertakan baris baharu:

%%
asm\n |
auto\n |
rehat\n |
... dan lain-lain ...
tidak menentu\n |
manakala\n /* ia adalah kata kunci */

[az]+\n |
[az]+ |
.|\n /* itu bukan kata kunci */

Disusun dengan -Cf, ini adalah kira-kira sepantas seseorang boleh mendapatkan a flex pengimbas untuk melakukan ini
masalah tertentu.

Nota akhir: flex adalah perlahan apabila memadankan NUL, terutamanya apabila token mengandungi
berbilang NUL. Adalah lebih baik untuk menulis peraturan yang sepadan pendek jumlah teks jika ia
menjangkakan bahawa teks itu selalunya termasuk NUL.

Satu lagi nota terakhir mengenai prestasi: seperti yang dinyatakan di atas dalam bahagian Bagaimana Input
dipadankan, mengubah saiz secara dinamik yytext untuk menampung token yang besar adalah proses yang perlahan
kerana ia pada masa ini memerlukan token (besar) diimbas semula dari awal. Justeru
jika prestasi adalah penting, anda harus cuba memadankan kuantiti teks "besar" tetapi tidak
kuantiti "besar", dengan potongan antara kedua-duanya adalah kira-kira 8K aksara/token.

MENJANA C + + PENGImbas


flex menyediakan dua cara berbeza untuk menjana pengimbas untuk digunakan dengan C++. Cara pertama ialah
untuk hanya menyusun pengimbas yang dihasilkan oleh flex menggunakan pengkompil C++ dan bukannya C
penyusun. Anda tidak sepatutnya menghadapi sebarang ralat kompilasi (sila laporkan mana-mana yang anda temui kepada
alamat e-mel yang diberikan dalam bahagian Pengarang di bawah). Anda kemudian boleh menggunakan kod C++ dalam
tindakan peraturan dan bukannya kod C. Ambil perhatian bahawa sumber input lalai untuk pengimbas anda
kekal yyin, dan gema lalai masih dilakukan untuk yyout. Kedua-dua ini kekal FAIL *
pembolehubah dan bukan C++ anak sungai.

Vous penggunaan pouvez aussi flex untuk menjana kelas pengimbas C++, menggunakan -+ pilihan (atau,
setara, %pilihan c++), yang ditentukan secara automatik jika nama flex
boleh laku berakhir dengan '+', seperti lentur++. Apabila menggunakan pilihan ini, flex lalai kepada
menjana pengimbas kepada fail lex.yy.cc bukan lex.yy.c. Pengimbas yang dihasilkan
termasuk fail pengepala FlexLexer.h, yang mentakrifkan antara muka kepada dua kelas C++.

Kelas pertama, FlexLexer, menyediakan kelas asas abstrak yang mentakrifkan pengimbas umum
antara muka kelas. Ia menyediakan fungsi ahli berikut:

malar char* YYText()
mengembalikan teks token yang paling baru dipadankan, bersamaan dengan yytext.

int YYLeng()
mengembalikan panjang token yang paling baru dipadankan, bersamaan dengan yyleng.

int lineno() malar
mengembalikan nombor baris input semasa (lihat %pilihan yylineno), or 1 if %pilihan
yylineno tidak digunakan.

membatalkan set_debug( int bendera )
menetapkan bendera penyahpepijatan untuk pengimbas, bersamaan dengan menugaskan kepada yy_flex_debug
(lihat bahagian Pilihan di atas). Ambil perhatian bahawa anda mesti membina pengimbas menggunakan
%pilihan debug untuk memasukkan maklumat penyahpepijatan di dalamnya.

int nyahpepijat() malar
mengembalikan tetapan semasa bendera penyahpepijatan.

Turut disediakan adalah fungsi ahli yang setara dengan yy_switch_to_buffer(), yy_create_buffer()
(walaupun hujah pertama adalah std::istream* penunjuk objek dan bukan a FAIL*),
yy_flush_buffer(), yy_delete_buffer(), and yyrestart() (sekali lagi, hujah pertama ialah a
std::istream* penunjuk objek).

Kelas kedua ditakrifkan dalam FlexLexer.h is yyFlexLexer, yang berasal dari FlexLexer.
Ia mentakrifkan fungsi ahli tambahan berikut:

yyFlexLexer( std::istream* arg_yyin = 0, std::ostream* arg_yyyout = 0 )
membina a yyFlexLexer objek menggunakan aliran yang diberikan untuk input dan output. Jika
tidak dinyatakan, strim lalai kepada cin and cout, masing-masing.

maya int yylex()
menjalankan peranan yang sama ialah yylex() lakukan untuk pengimbas lentur biasa: ia mengimbas
aliran input, menggunakan token, sehingga tindakan peraturan mengembalikan nilai. Jika awak
memperoleh subkelas S dari yyFlexLexer dan ingin mengakses fungsi ahli dan
pembolehubah daripada S di dalam yylex(), maka anda perlu menggunakan %pilihan yyclass="S" untuk memaklumkan
flex bahawa anda akan menggunakan subkelas itu dan bukannya yyFlexLexer. Dalam kes ini,
bukannya menjana yyFlexLexer::yylex(), flex menjana S::yylex() (dan juga
menghasilkan dummy yyFlexLexer::yylex() yang memanggil yyFlexLexer::LexerError() if
dipanggil).

maya membatalkan switch_streams(std::istream* new_in = 0,
std::ostream* baru_keluar = 0) menetapkan semula yyin kepada new_in (jika bukan nol) dan yyout kepada
baru_keluar (ditto), memadamkan penimbal input sebelumnya jika yyin ditugaskan semula.

int yylex( std::istream* new_in, std::ostream* baru_keluar = 0 )
mula-mula menukar aliran input melalui suis_strim( new_in, baru_keluar ) dan kemudian
mengembalikan nilai yylex().

Di samping itu, yyFlexLexer mentakrifkan fungsi maya dilindungi berikut yang anda boleh
takrifkan semula dalam kelas terbitan untuk menyesuaikan pengimbas:

maya int LexerInput( char* buf, int max_size )
membaca sehingga max_size watak ke dalam penggemar dan mengembalikan bilangan aksara yang dibaca.
Untuk menunjukkan akhir input, kembalikan 0 aksara. Ambil perhatian bahawa pengimbas "interaktif".
(Lihat -B and -I bendera) tentukan makro YY_INTERAKTIF. Jika anda mentakrifkan semula
LexerInput() dan perlu mengambil tindakan yang berbeza bergantung pada sama ada atau tidak
pengimbas mungkin mengimbas sumber input interaktif, anda boleh menguji untuk
kehadiran nama ini melalui #ifdef.

maya membatalkan LexerOutput( malar char* buf, int saiz )
menulis saiz aksara daripada penimbal buf, yang, semasa ditamatkan NUL, boleh
juga mengandungi NUL "dalaman" jika peraturan pengimbas boleh memadankan teks dengan masuk NUL
Mereka.

maya membatalkan LexerError( malar char* msg )
melaporkan mesej ralat yang membawa maut. Versi lalai fungsi ini menulis
mesej kepada strim cerr dan keluar.

Perhatikan bahawa a yyFlexLexer objek mengandunginya keseluruhan keadaan pengimbasan. Oleh itu anda boleh menggunakan sedemikian
objek untuk mencipta pengimbas masuk semula. Anda boleh membuat seketika beberapa kejadian yang sama
yyFlexLexer kelas, dan anda juga boleh menggabungkan berbilang kelas pengimbas C++ bersama-sama dalam
program yang sama menggunakan -P pilihan yang dibincangkan di atas.

Akhir sekali, perhatikan bahawa %array ciri tidak tersedia untuk kelas pengimbas C++; kamu mesti
penggunaan %penunjuk (lalai).

Berikut ialah contoh pengimbas C++ yang mudah:

// Contoh penggunaan kelas pengimbas flex C++.

%{
int mylineno = 0;
%}

rentetan \"[^\n"]+\"

ws [ \t]+

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

%%

{ws} /* langkau tempat kosong dan tab */

"/*" {
int c;

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

else if(c == '*')
{
if((c = yyinput()) == '/')
memecahkan;
lagi
nyahput(c);
}
}
}

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

\n mylineno++;

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

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

%%

int utama( int /* argc */, char** /* argv */ )
{
FlexLexer* lexer = yyFlexLexer baharu;
while(lexer->yylex() != 0)
;
0 kembali;
}
Jika anda ingin mencipta berbilang kelas lexer (berbeza), anda menggunakan -P bendera (atau
awalan= pilihan) untuk menamakan semula setiap satu yyFlexLexer kepada yang lain xxFlexLexer. Anda kemudian boleh
termasuk dalam sumber anda yang lain sekali setiap kelas lexer, menamakan semula dahulu
yyFlexLexer seperti berikut:

#undef yyFlexLexer
#define yyFlexLexer xxFlexLexer
#termasuk

#undef yyFlexLexer
#define yyFlexLexer zzFlexLexer
#termasuk

jika, sebagai contoh, anda menggunakan %pilihan awalan="xx" untuk salah satu pengimbas anda dan %pilihan
awalan="zz" untuk yang lain.

PENTING: bentuk kelas pengimbasan sekarang ialah eksperimen dan mungkin berubah
ketara antara keluaran utama.

TIDAK SESUAI DENGAN LEX DAN POSIX


flex ialah penulisan semula AT&T Unix lex alat (kedua-dua pelaksanaan tidak berkongsi apa-apa
kod, walaupun), dengan beberapa sambungan dan ketidakserasian, yang kedua-duanya membimbangkan
mereka yang ingin menulis pengimbas boleh diterima sama ada pelaksanaan. Flex adalah sepenuhnya
mematuhi POSIX lex spesifikasi, kecuali apabila menggunakan %penunjuk (lalai),
panggilan ke unput() memusnahkan kandungan yytext, yang bertentangan dengan POSIX
spesifikasi.

Dalam bahagian ini kita membincangkan semua bidang ketidakserasian yang diketahui antara flex, AT&T
lex, dan spesifikasi POSIX.

flex's -l pilihan menghidupkan keserasian maksimum dengan AT&T asal lex pelaksanaan,
pada kos kerugian besar dalam prestasi pengimbas yang dihasilkan. Kami perhatikan di bawah yang mana
ketidakserasian boleh diatasi menggunakan -l pilihan.

flex serasi sepenuhnya dengan lex dengan pengecualian berikut:

- Yang tidak berdokumen lex pembolehubah dalaman pengimbas yylineno tidak disokong melainkan -l
or %pilihan yylineno digunakan.

yylineno hendaklah dikekalkan berdasarkan setiap penimbal, bukannya setiap pengimbas
(pembolehubah global tunggal) asas.

yylineno bukan sebahagian daripada spesifikasi POSIX.

- The input() rutin tidak boleh ditakrifkan semula, walaupun ia mungkin dipanggil untuk membaca aksara
mengikut apa sahaja yang telah dipadankan dengan peraturan. Jika input() menemui penghujung-
fail biasa ywrap() pemprosesan dilakukan. A ``sebenar'' akhir fail dikembalikan oleh
input() as EOF.

Input sebaliknya dikawal dengan mentakrifkan YY_INPUT makro.

. flex sekatan itu input() tidak boleh ditakrifkan semula adalah selaras dengan
Spesifikasi POSIX, yang hanya tidak menyatakan sebarang cara untuk mengawal
input pengimbas selain dengan membuat tugasan awal kepada yyin.

- The unput() rutin tidak boleh ditakrifkan semula. Sekatan ini adalah mengikut
POSIX.

- flex pengimbas tidak seperti reentrant lex pengimbas. Khususnya, jika anda mempunyai
pengimbas interaktif dan pengendali gangguan yang melompat jauh keluar dari pengimbas,
dan pengimbas kemudiannya dipanggil semula, anda mungkin mendapat mesej berikut:

ralat dalaman pengimbas flex maut--penghujung penimbal terlepas

Untuk memasukkan semula pengimbas, gunakan dahulu

yyrestart(yyin);

Ambil perhatian bahawa panggilan ini akan membuang sebarang input buffer; selalunya ini bukan a
masalah dengan pengimbas interaktif.

Juga ambil perhatian bahawa kelas pengimbas C++ fleksibel adalah reentrant, jadi jika menggunakan C++ adalah pilihan
untuk anda, anda harus menggunakannya sebaliknya. Lihat "Menjana Pengimbas C++" di atas untuk
butiran.

- pengeluaran() tidak disokong. Output daripada ECHO makro dilakukan pada penuding fail
yyout (lalai stdout).

pengeluaran() bukan sebahagian daripada spesifikasi POSIX.

- lex tidak menyokong syarat permulaan eksklusif (%x), walaupun ia berada dalam POSIX
spesifikasi.

- Apabila definisi dikembangkan, flex melampirkannya dalam kurungan. Dengan lex, the
Berikut:

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

tidak akan sepadan dengan rentetan "foo" kerana apabila makro dikembangkan peraturannya adalah
bersamaan dengan "foo[AZ][A-Z0-9]*?" dan keutamaan adalah sedemikian rupa sehingga '?' ialah
dikaitkan dengan "[A-Z0-9]*". Dengan lentur, peraturan akan dikembangkan kepada "foo([AZ][A-
Z0-9]*)?" dan oleh itu rentetan "foo" akan sepadan.

Perhatikan bahawa jika definisi bermula dengan ^ atau berakhir dengan $ maka ia adalah tidak berkembang
dengan kurungan, untuk membolehkan pengendali ini muncul dalam definisi tanpa kehilangan
makna istimewa mereka. Tetapi , /, and < > operator tidak boleh digunakan dalam a
flex definisi.

Menggunakan -l hasil dalam lex tingkah laku tanpa kurungan di sekeliling definisi.

Spesifikasi POSIX ialah definisi disertakan dalam kurungan.

- Beberapa pelaksanaan lex benarkan tindakan peraturan bermula pada baris yang berasingan, jika
corak peraturan mempunyai ruang kosong mengekori:

%%
foo|bar
{ foobar_action(); }

flex tidak menyokong ciri ini.

- The lex %r (jana pengimbas Ratfor) pilihan tidak disokong. Ia bukan sebahagian daripada
spesifikasi POSIX.

- Selepas panggilan ke unput(), yytext tidak ditentukan sehingga token seterusnya dipadankan,
melainkan pengimbas dibina menggunakan %array. Ini tidak berlaku dengan lex atau
Spesifikasi POSIX. The -l pilihan menghapuskan ketidakserasian ini.

- Keutamaan daripada {} (julat angka) adalah berbeza. lex menafsirkan
"abc{1,3}" sebagai "padankan satu, dua atau tiga kejadian 'abc'", manakala flex
mentafsirkannya sebagai "padan 'ab' diikuti dengan satu, dua atau tiga kejadian 'c'".
Yang terakhir ini bersetuju dengan spesifikasi POSIX.

- Keutamaan daripada ^ operator berbeza. lex mentafsirkan "^foo|bar" sebagai "padanan
sama ada 'foo' pada permulaan baris, atau 'bar' di mana-mana", sedangkan flex
mentafsirkannya sebagai "padan sama ada 'foo' atau 'bar' jika ia datang pada permulaan a
baris". Yang terakhir ini bersetuju dengan spesifikasi POSIX.

- Pengisytiharan saiz jadual khas seperti %a disokong oleh lex tidak diperlukan oleh
flex pengimbas; flex mengabaikan mereka.

- Nama FLEX_SCANNER adalah #define'd supaya pengimbas boleh ditulis untuk digunakan dengan sama ada
flex or lex. Pengimbas juga termasuk YY_FLEX_MAJOR_VERSION and YY_FLEX_MINOR_VERSION
menunjukkan versi mana flex menghasilkan pengimbas (contohnya, untuk 2.5
keluaran, takrifan ini ialah 2 dan 5 masing-masing).

Berikut flex ciri tidak termasuk dalam lex atau spesifikasi POSIX:

Pengimbas C++
%pilihan
mulakan skop keadaan
mulakan susunan keadaan
pengimbas interaktif/bukan interaktif
yy_scan_string() dan rakan
tamat tempoh ()
yy_set_interactive()
yy_set_bol()
YY_AT_BOL()
< >
<*>
YY_DECL
YY_START
YY_USER_ACTION
YY_USER_INIT
#arahan talian
%{}'s sekitar tindakan
berbilang tindakan pada satu baris

ditambah dengan hampir semua bendera flex. Ciri terakhir dalam senarai merujuk kepada fakta bahawa
bersama flex anda boleh meletakkan berbilang tindakan pada baris yang sama, dipisahkan dengan koma bertitik, manakala
bersama lex, berikut

foo handle_foo(); ++num_foos_seen;

adalah (agak menghairankan) dipotong kepada

foo handle_foo();

flex tidak memotong tindakan. Tindakan yang tidak disertakan dalam pendakap adalah mudah
ditamatkan di hujung talian.

DIAGNOSTIK


amaran, memerintah tidak boleh be dipadankan menunjukkan bahawa peraturan yang diberikan tidak boleh dipadankan kerana ia
mengikuti peraturan lain yang akan sentiasa sepadan dengan teks yang sama dengannya. Sebagai contoh, dalam
"foo" berikut tidak boleh dipadankan kerana ia datang selepas peraturan "catch-all" pengecam:

[az]+ got_identifier();
foo got_foo();

Menggunakan REJEK dalam pengimbas menghalang amaran ini.

amaran, -s pilihan diberikan tetapi lalai memerintah boleh be dipadankan bermakna ia mungkin
(mungkin hanya dalam keadaan permulaan tertentu) bahawa peraturan lalai (padanan dengan mana-mana single
aksara) adalah satu-satunya yang akan sepadan dengan input tertentu. Sejak -s telah diberikan,
mungkin ini tidak dimaksudkan.

tolak_digunakan_tetapi_tidak_dikesan undefined or yymore_use_but_not_detected undefined - Ini
ralat boleh berlaku pada masa penyusunan. Mereka menunjukkan bahawa pengimbas menggunakan REJEK or yymore()
tetapi itu flex gagal untuk melihat fakta, bermakna itu flex mengimbas dua bahagian pertama
mencari kejadian tindakan ini dan gagal menemui apa-apa, tetapi entah bagaimana anda menyelinap
beberapa dalam (melalui fail #include, sebagai contoh). guna %pilihan menolak or %pilihan yymore kepada
menunjukkan kepada flex bahawa anda benar-benar menggunakan ciri ini.

flex pengimbas tersekat - pengimbas yang disusun dengan -s telah menemui rentetan input yang
tidak dipadankan dengan mana-mana peraturannya. Ralat ini juga boleh berlaku kerana masalah dalaman.

token tinggi besar, melebihi YYLMAX - kegunaan pengimbas anda %array dan salah satu peraturannya sepadan dengan a
rentetan lebih panjang daripada YYLMAX pemalar (8K bait secara lalai). Anda boleh meningkatkan nilai
dengan #define'ing YYLMAX dalam bahagian takrifan anda flex input.

pengimbas memerlukan -8 bendera kepada penggunaan yang watak 'x' - Spesifikasi pengimbas anda termasuk
mengenali aksara 8-bit 'x' dan anda tidak menyatakan bendera -8 dan pengimbas anda
lalai kepada 7-bit kerana anda menggunakan -Cf or -CF pilihan pemampatan meja. Lihat
perbincangan mengenai -7 bendera untuk butiran.

flex pengimbas menolak kembali limpahan - awak guna unput() untuk menolak begitu banyak teks yang
penimbal pengimbas tidak dapat menahan kedua-dua teks ditolak dan token semasa masuk yytext.
Sebaik-baiknya pengimbas harus mengubah saiz penimbal secara dinamik dalam kes ini, tetapi pada masa ini ia
tidak.

input penampan melimpah, tidak boleh membesarkan penampan kerana pengimbas menggunakan REJEK - pengimbas itu
berusaha untuk memadankan token yang sangat besar dan diperlukan untuk mengembangkan penimbal input. ini
tidak berfungsi dengan pengimbas yang digunakan TOLAK.

maut flex pengimbas dalaman ralat--akhir of penampan terlepas - Ini boleh berlaku dalam pengimbas
yang dimasukkan semula selepas lompat jauh telah melompat keluar (atau melebihi) pengaktifan pengimbas
bingkai. Sebelum memasukkan semula pengimbas, gunakan:

yyrestart(yyin);

atau, seperti yang dinyatakan di atas, beralih kepada menggunakan kelas pengimbas C++.

tinggi banyak permulaan syarat in <> membina! - anda menyenaraikan lebih banyak syarat permulaan dalam <>
membina daripada wujud (jadi anda mesti telah menyenaraikan sekurang-kurangnya satu daripadanya dua kali).

Gunakan freebsd-lex dalam talian menggunakan perkhidmatan onworks.net


Pelayan & Stesen Kerja Percuma

Muat turun apl Windows & Linux

Arahan Linux

Ad




×
Pengiklanan
❤ ️Beli, tempah atau beli di sini — tanpa kos, membantu memastikan perkhidmatan percuma.