InggrisPerancisSpanyol

favorit OnWorks

pasak - Online di Cloud

Jalankan pasak di penyedia hosting gratis OnWorks melalui Ubuntu Online, Fedora Online, emulator online Windows, atau emulator online MAC OS

Ini adalah command peg yang dapat dijalankan di penyedia hosting gratis OnWorks menggunakan salah satu dari beberapa workstation online gratis kami seperti Ubuntu Online, Fedora Online, Windows online emulator atau MAC OS online emulator

PROGRAM:

NAMA


pasak, kaki - generator parser

RINGKASAN


pasak [-hvV -keluaran] [nama file ...]
kaki [-hvV -keluaran] [nama file ...]

DESKRIPSI


pasak dan kaki adalah alat untuk menghasilkan parser turunan rekursif: program yang melakukan
pencocokan pola pada teks. Mereka memproses Parsing Expression Grammar (PEG) [Ford 2004] untuk
menghasilkan program yang mengenali kalimat hukum tata bahasa itu. pasak memproses PEG
ditulis menggunakan sintaks asli yang dijelaskan oleh Ford; kaki memproses PEG yang ditulis menggunakan
sintaks dan konvensi yang sedikit berbeda yang dimaksudkan untuk membuatnya menarik
pengganti parser yang dibuat dengan lex(1) dan yacc(1). Tidak seperti lex dan yacc, pasak dan kaki
mendukung backtracking tanpa batas, memberikan pilihan yang teratur sebagai sarana untuk disambiguasi, dan
dapat menggabungkan pemindaian (analisis leksikal) dan penguraian (analisis sintaksis) menjadi satu
aktivitas.

pasak membaca yang ditentukan nama files, atau input standar jika tidak ada nama files diberikan, untuk
tata bahasa menggambarkan parser untuk menghasilkan. pasak kemudian menghasilkan file sumber C yang
mendefinisikan fungsi yyparse(). File sumber C ini dapat dimasukkan, atau dikompilasi dan kemudian
terkait dengan, program klien. Setiap kali program klien memanggil kamu menguraikan() pengurai
menggunakan teks input sesuai dengan aturan penguraian, mulai dari aturan pertama di
tatabahasa. kamu menguraikan() mengembalikan bukan nol jika input dapat diuraikan sesuai dengan
tata bahasa; itu mengembalikan nol jika input tidak dapat diuraikan.

Awalan 'yy' atau 'YY' ditambahkan ke semua simbol yang terlihat secara eksternal di file yang dihasilkan
pengurai Ini dimaksudkan untuk mengurangi risiko pencemaran namespace dalam program klien.
(Pilihan 'yy' bersifat historis; lihat lex(1) dan yacc(1), misalnya.)

PILIHAN


pasak dan kaki memberikan opsi berikut:

-h mencetak ringkasan opsi yang tersedia dan kemudian keluar.

-keluaran
menulis parser yang dihasilkan ke file keluaran bukannya keluaran standar.

-v menulis informasi verbose ke kesalahan standar saat bekerja.

-V menulis informasi versi ke kesalahan standar lalu keluar.

A SEDERHANA CONTOH


Berikut ini pasak input menentukan tata bahasa dengan aturan tunggal (disebut 'mulai') yaitu
puas ketika input berisi string "nama pengguna".

mulai <- "nama pengguna"

(Tanda kutip adalah tidak bagian dari teks yang cocok; mereka berfungsi untuk menunjukkan literal
string yang akan dicocokkan.) Dengan kata lain, kamu menguraikan() di sumber C yang dihasilkan akan kembali
bukan nol hanya jika delapan karakter berikutnya membaca dari ejaan input kata "nama pengguna".
Jika input berisi hal lain, kamu menguraikan() mengembalikan nol dan tidak akan ada input
dikonsumsi. (Panggilan selanjutnya ke kamu menguraikan() juga akan mengembalikan nol, karena parsernya adalah
secara efektif diblokir mencari string "nama pengguna".) Untuk memastikan kemajuan, kami dapat menambahkan
klausa alternatif untuk aturan 'mulai' yang akan cocok dengan karakter tunggal apa pun jika "nama pengguna"
tidak ditemukan.

mulai <- "nama pengguna"
/.

kamu menguraikan() sekarang selalu mengembalikan bukan nol (kecuali di akhir input). Melakukan
sesuatu yang berguna kita dapat menambahkan tindakan ke aturan. Tindakan ini dilakukan setelah a
kecocokan lengkap ditemukan (dimulai dari aturan pertama) dan dipilih sesuai dengan
'jalur' diambil melalui tata bahasa untuk mencocokkan input. (Para ahli bahasa akan menyebut jalan ini sebagai
'penanda frasa'.)

mulai <- "nama pengguna" { printf("%s\n", getlogin()); }
/ < . > { putchar(yytext[0]); }

Baris pertama menginstruksikan parser untuk mencetak nama login pengguna kapan pun ia melihatnya
"nama pengguna" di input. Jika kecocokan itu gagal, baris kedua memberi tahu parser untuk bergema
karakter berikutnya pada input output standar. Pengurai kami sekarang berfungsi dengan baik
bekerja: itu akan menyalin input ke output, mengganti semua kemunculan "nama pengguna" dengan
nama akun pengguna.

Perhatikan tanda kurung sudut ('<' dan '>') yang ditambahkan pada alternatif kedua. Ini
tidak berpengaruh pada makna aturan, tetapi berfungsi untuk membatasi teks yang tersedia untuk
tindakan berikut dalam variabel yyteks.

Jika tata bahasa di atas ditempatkan dalam file nama pengguna.peg, menjalankan perintah

pasak -o nama pengguna.c nama pengguna. pasak

akan menyimpan pengurai yang sesuai dalam file nama pengguna.c. Untuk membuat program yang lengkap
parser ini dapat dimasukkan oleh program C sebagai berikut.

#termasuk /* printf(), putchar() */
#termasuk /* getlogin() */

#sertakan "nama pengguna.c" /* yyparse() */

int main ()
{
while (yyparse()) /* ulangi sampai EOF */
;
0 kembali;
}

PEG TAHU BAHASA


Tata bahasa terdiri dari seperangkat aturan bernama.

nama <- pola

belt hold mengandung satu atau lebih elemen berikut.

nama Elemen adalah singkatan dari seluruh pola dalam aturan dengan yang diberikan nama.

"karakter"
Karakter atau string yang diapit tanda kutip ganda dicocokkan secara harfiah. ANSI C
urutan pelarian dikenali dalam karakter.

'karakter'
Karakter atau string yang diapit dalam tanda kutip tunggal dicocokkan secara harfiah, seperti di atas.

[karakter]
Satu set karakter yang diapit tanda kurung siku cocok dengan karakter tunggal mana pun dari
set, dengan karakter escape yang dikenali seperti di atas. Jika himpunan dimulai dengan
uparrow (^) maka himpunan dinegasikan (elemen cocok dengan karakter apa pun tidak dalam
mengatur). Setiap pasangan karakter yang dipisahkan dengan tanda hubung (-) mewakili kisaran
karakter dari yang pertama ke yang kedua, inklusif. Satu karakter alfabet
atau garis bawah dicocokkan dengan set berikut.

[a-zA-Z_]

Demikian pula, berikut ini cocok dengan karakter non-digit tunggal.

[^0-9]

. Sebuah titik cocok dengan karakter apa pun. Perhatikan bahwa satu-satunya saat ini gagal adalah di akhir
file, di mana tidak ada karakter yang cocok.

( belt hold )
Tanda kurung digunakan untuk pengelompokan (memodifikasi prioritas operator
dijelaskan di bawah).

{ tindakan }
Tanda kurung kurawal mengelilingi tindakan. Tindakannya adalah kode sumber C sewenang-wenang menjadi
dieksekusi pada akhir pencocokan. Setiap kawat gigi dalam aksi harus benar
bersarang. Teks input apa pun yang dicocokkan sebelum aksi dan dibatasi oleh sudut
tanda kurung (lihat di bawah) tersedia dalam aksi sebagai isi dari
susunan karakter yyteks. Panjang (jumlah karakter dalam) yyteks is
tersedia dalam variabel yyleng. (Nama variabel ini bersifat historis; lihat
lex(1).)

< Braket sudut pembuka selalu cocok (tidak menggunakan input) dan menyebabkan parser
untuk mulai mengumpulkan teks yang cocok. Teks ini akan tersedia untuk tindakan di
variabel yyteks.

> Braket sudut penutup selalu cocok (tidak menggunakan input) dan menyebabkan parser
untuk berhenti mengumpulkan teks untuk yyteks.

Atas elemens dapat dibuat opsional dan/atau dapat diulang dengan sufiks berikut:

elemen ?
Elemen ini opsional. Jika ada pada input, itu dikonsumsi dan pertandingan
berhasil. Jika tidak ada pada input, tidak ada teks yang digunakan dan kecocokan berhasil
pula.

elemen +
Elemen ini dapat diulang. Jika ada pada input, satu atau lebih kemunculan dari
elemen dikonsumsi dan pertandingan berhasil. Jika tidak ada kejadian elemen adalah
hadir pada input, pertandingan gagal.

elemen *
Elemen ini opsional dan dapat diulang. Jika ada pada input, satu atau lebih
kejadian dari elemen dikonsumsi dan pertandingan berhasil. Jika tidak ada kejadian
elemen hadir pada input, pertandingan tetap berhasil.

Elemen dan sufiks di atas dapat diubah menjadi predikat (yang cocok dengan sembarang
masukan teks dan selanjutnya berhasil atau gagal tanpa mengkonsumsi input itu) dengan
awalan berikut:

& elemen
Predikat berhasil hanya jika elemen dapat dicocokkan. Masukkan teks yang dipindai saat
sesuai elemen tidak dikonsumsi dari input dan tetap tersedia untuk
pencocokan selanjutnya.

! elemen
Predikat berhasil hanya jika elemen tidak dapat ditandingi. Masukkan teks yang dipindai saat
sesuai elemen tidak dikonsumsi dari input dan tetap tersedia untuk
pencocokan selanjutnya. Sebuah idiom populer adalah

!.

yang cocok dengan akhir file, setelah karakter terakhir dari input sudah
telah dikonsumsi.

Bentuk khusus dari predikat '&' disediakan:

&{ ekspresi }
Dalam predikat ini C . sederhana ekspresi (tidak pernyataan) dievaluasi segera
ketika parser mencapai predikat. jika ekspresi menghasilkan bukan nol (benar)
'pertandingan' berhasil dan pengurai melanjutkan dengan elemen berikutnya dalam pola.
Jika ekspresi menghasilkan nol (salah) 'kecocokan' gagal dan parser mundur ke
mencari parse alternatif dari input.

Beberapa elemen (dengan atau tanpa awalan dan akhiran) dapat digabungkan menjadi a urutan
dengan menuliskannya satu demi satu. Seluruh urutan cocok hanya jika setiap individu
elemen di dalamnya cocok, dari kiri ke kanan.

Urutan dapat dipisahkan menjadi alternatif terputus-putus oleh operator pergantian '/'.

urutan-1 / urutan-2 / ... / urutan-N
Setiap urutan dicoba secara bergantian sampai salah satu dari mereka cocok, pada saat itu cocok
untuk pola keseluruhan berhasil. Jika tidak ada urutan yang cocok maka yang cocok
dari pola keseluruhan gagal.

Akhirnya, tanda pound (#) memperkenalkan komentar (dibuang) yang berlanjut hingga akhir
dari garis.

Untuk meringkas hal di atas, pengurai mencoba mencocokkan teks input dengan sebuah pola
mengandung literal, nama (mewakili aturan lain), dan berbagai operator (ditulis sebagai
prefiks, sufiks, penjajaran untuk pengurutan dan dan operator pergantian sisipan) yang
memodifikasi bagaimana elemen-elemen dalam pola dicocokkan. Pertandingan dibuat dari kiri ke
benar, 'turun' ke dalam sub-aturan bernama saat ditemui. Jika proses pencocokan
gagal, parser 'mundur' ('memutar ulang' input dengan tepat dalam proses) ke
temukan 'jalan' alternatif terdekat melalui tata bahasa. Dengan kata lain pengurai
melakukan pencarian mendalam-pertama, kiri-ke-kanan untuk jalur pertama yang berhasil dicocokkan
melalui aturan. Jika ditemukan, tindakan di sepanjang jalur yang berhasil akan dieksekusi (dalam
urutan mereka ditemui).

Perhatikan bahwa predikat dievaluasi segera selama mencari kecocokan yang sukses,
karena mereka berkontribusi pada keberhasilan atau kegagalan pencarian. Tindakan, bagaimanapun, adalah
dievaluasi hanya setelah kecocokan yang berhasil ditemukan.

PEG TATABAHASA UNTUK PEG TAHU BAHASA


Tata bahasa untuk pasak tata bahasa ditunjukkan di bawah ini. Ini akan menggambarkan dan memformalkan
deskripsi di atas.

Tata Bahasa <- Definisi Spasi+ EndOfFile

Definisi <- Pengidentifikasi Ekspresi LEFTARROW
Ekspresi <- Urutan ( Urutan SLASH )*
Urutan <- Awalan*
Awalan <- DAN Tindakan
/ ( DAN | TIDAK )? Akhiran
Suffix <- Primer ( QUERY / STAR / PLUS )?
<- Pengidentifikasi Utama !LEFTARROW
/ BUKA Ekspresi TUTUP
/ harfiah
/ Kelas
/ DOT
/ Tindakan
/ MULAI
/ AKHIR

Identifier <- < IdentStart IdentCont* > Spasi
IdentStart <- [a-zA-Z_]
IdentCont <- IdentStart / [0-9]
Literal <- ['] < ( !['] Char )* > ['] Spasi
/ ["] < ( !["] Char )* > ["] Spasi
Kelas <- '[' < ( !']' Rentang )* > ']' Spasi
Rentang <- Char '-' Char / Char
Char <- '\\' [abefnrtv'"\[\]\\]
/ '\\' [0-3][0-7][0-7]
/ '\\' [0-7][0-7]?
/ '\\' '-'
/ !'\\' .
LEFTARROW <- '<-' Spasi
SLASH <- '/' Spasi
DAN <- '&' Spasi
BUKAN <- '!' Jarak
PERTANYAAN <- '?' Jarak
BINTANG <- '*' Spasi
PLUS <- '+' Spasi
BUKA <- '(' Spasi
TUTUP <- ')' Spasi
titik <- '.' Jarak
Spasi <- ( Spasi / Komentar )*
Komentar <- '#' ( !EndOfLine . )* EndOfLine
Spasi <- ' ' / '\t' / EndOfLine
EndOfLine <- '\r\n' / '\n' / '\r'
EndOfFile <- !.
Tindakan <- '{' < [^}]* > '}' Spasi
MULAI <- '<' Spasi
END <- '>' Spasi

LEG TAHU BAHASA


kaki adalah varian dari pasak yang menambahkan beberapa fitur dari lex(1) dan yacc(1). Ini berbeda dari
pasak dengan cara-cara berikut.

%{ teks... %}
Bagian deklarasi dapat muncul di mana pun definisi aturan diharapkan. NS
teks antara pembatas '%{' dan '%}' disalin kata demi kata ke C . yang dihasilkan
kode pengurai sebelum kode yang mengimplementasikan parser itu sendiri.

nama = belt hold
Operator 'tugas' menggantikan operator panah kiri '<-'.

nama aturan
Tanda hubung dapat muncul sebagai huruf dalam nama aturan. Setiap tanda hubung diubah menjadi
garis bawah dalam kode sumber C yang dihasilkan. Tanda hubung tunggal '-' adalah
nama aturan hukum.

- = [\t\n\r]*
angka = [0-9]+ -
nama = [a-zA-Z_][a-zA_Z_0-9]* -
l-paren = '(' -
r-paren = ')' -

Contoh ini menunjukkan bagaimana spasi yang diabaikan dapat terlihat jelas saat membaca tata bahasa
namun tidak mengganggu ketika ditempatkan secara bebas di akhir setiap aturan yang terkait dengan
sebuah elemen leksikal.

bagian-1 | bagian-2
Operator pergantian adalah bilah vertikal '|' daripada garis miring '/'. NS
pasak memerintah

nama <- urutan-1
/ urutan-2
/ urutan-3

Oleh karena itu ditulis

nama = urutan-1
| urutan-2
| urutan-3
;

in kaki (dengan titik koma terakhir sebagai opsional, seperti yang dijelaskan selanjutnya).

exp ~ { tindakan }
Operator postfix ~{ tindakan } dapat ditempatkan setelah ekspresi apa pun dan akan berperilaku
seperti tindakan normal (kode C sewenang-wenang) kecuali bahwa itu dipanggil hanya ketika exp
gagal. Ini mengikat kurang erat daripada operator lain kecuali pergantian dan
pengurutan, dan dimaksudkan untuk membuat penanganan kesalahan dan kode pemulihan lebih mudah untuk
menulis. Perhatikan bahwa yyteks dan yyleng tidak tersedia di dalam tindakan ini, tetapi
variabel penunjuk yy tersedia untuk memberikan akses kode ke semua yang ditentukan pengguna
anggota negara parser (lihat "MENYESUAIKAN PARSER" di bawah). Perhatikan juga bahwa
exp selalu merupakan ekspresi tunggal; untuk meminta tindakan kesalahan untuk kegagalan apa pun di dalam
urutan, tanda kurung harus digunakan untuk mengelompokkan urutan menjadi satu
ekspresi.

aturan = e1 e2 e3 ~{ error("e[12] ok; e3 gagal"); }
| ...

rule = (e1 e2 e3) ~{ error("salah satu dari e[123] gagal"); }
| ...

belt hold ;
Tanda titik koma secara opsional dapat mengakhiri a belt hold.

%% teks...
Sebuah persen ganda '%%' mengakhiri bagian aturan (dan deklarasi) dari
tata bahasa. Semua teks berikut '%%' disalin kata demi kata ke kode parser C yang dihasilkan
setelah kode implementasi parser.

$$ = nilai
Sub-aturan dapat mengembalikan semantik nilai dari suatu tindakan dengan menugaskannya ke
variabel semu '$$'. Semua nilai semantik harus memiliki tipe yang sama (yang defaultnya
menjadi 'int'). Tipe ini dapat diubah dengan mendefinisikan YYSTYPE di bagian deklarasi.

identifier:nama
Nilai semantik yang dikembalikan (dengan menetapkan ke '$$') dari sub-aturan nama is
terkait dengan identifier dan dapat dirujuk dalam tindakan selanjutnya.

Contoh kalkulator meja di bawah ini menggambarkan penggunaan '$$' dan ':'.

LEG CONTOH: A MEJA TULIS KALKULATOR


Ekstensi di kaki dijelaskan di atas memungkinkan parser dan evaluator yang berguna (termasuk
deklarasi, aturan tata bahasa, dan fungsi C pendukung seperti 'utama') untuk disimpan di dalam
satu file sumber. Untuk mengilustrasikan ini, kami menunjukkan kalkulator meja sederhana yang mendukung
empat operator aritmatika umum dan variabel bernama. Hasil antara
evaluasi aritmatika akan diakumulasikan pada tumpukan implisit dengan mengembalikannya sebagai
nilai semantik dari sub-aturan.

%{
#termasuk /* printf() */
#termasuk /* atoi() */
int var[26];
%}

Stmt = - e:Expr EOL { printf("%d\n", e); }
| ( !EOL . )* EOL { printf("kesalahan\n"); }

Ekspr = i:ID ASSIGN s:Jumlah { $$ = vars[i] = s; }
| s:Jumlah { $$ = s; }

Jumlah = l:Produk
( PLUS r:Produk { l += r; }
| MINUS r:Produk { l -= r; }
)* { $$ = aku; }

Produk = l:Nilai
( KALI r:Nilai { l *= r; }
| BAGI r:Nilai { l /= r; }
)* { $$ = aku; }

Nilai = i:NUMBER { $$ = atoi(yytext); }
| i:ID !ASSIGN { $$ = vars[i]; }
| BUKA i:Expr TUTUP { $$ = i; }

NOMOR = < [0-9]+ > - { $$ = atoi(yytext); }
ID = < [az] > - { $$ = yytext[0] - 'a'; }
TUGAS = '=' -
DITAMBAH = '+' -
MINUS = '-' -
KALI = '*' -
BAGI = '/' -
BUKA = '(' -
TUTUP = ')' -

- = [\t]*
EOL = '\n' | '\r\n' | '\r' | ';'

%%

int main ()
{
sementara (yyparse())
;
0 kembali;
}

LEG TATABAHASA UNTUK LEG TAHU BAHASA


Tata bahasa untuk kaki tata bahasa ditunjukkan di bawah ini. Ini akan menggambarkan dan memformalkan
deskripsi di atas.

tata bahasa = -
( deklarasi | definisi )+
cuplikan? akhir file

deklarasi = '%{' < ( !'%}' . )* > RPERCENT

cuplikan = '%%' < .* >

definisi = pengenal ekspresi SAMA SEMIKOLON?

ekspresi = urutan ( BAR urutan )*

urutan = kesalahan+

kesalahan = awalan (tindakan TILDE)?

awalan = DAN tindakan
| (DAN | TIDAK)? akhiran

akhiran = primer ( QUERY | STAR | PLUS )?

primer = pengenal pengenal COLON !EQUAL
| pengenal !SAMA
| ekspresi BUKA TUTUP
| harfiah
| kelas
| DOT
| tindakan
| MULAI
| AKHIR

pengenal = < [-a-zA-Z_][-a-zA-Z_0-9]* > -

literal = ['] < ( !['] char )* > ['] -
| ["] < ( !["] char )* > ["] -

kelas = '[' < ( !']' rentang )* > ']' -

rentang = char '-' char | arang

char = '\\' [abefnrtv'"\[\]\\]
| '\\' [0-3][0-7][0-7]
| '\\' [0-7][0-7]?
| !'\\' .

tindakan = '{' < kurung kurawal* > '}' -

kurung kurawal = '{' kurung kurawal* '}'
| !'}' .

SAMA = '=' -
titik dua = ':' -
titik koma = ';' -
BAR = '|' -
DAN = '&' -
TIDAK = '!' -
PERTANYAAN = '?' -
BINTANG = '*' -
DITAMBAH = '+' -
BUKA = '(' -
TUTUP = ')' -
titik = '.' -
MULAI = '<' -
SELESAI = '>' -
TILDE = '~' -
RPERCENT = '%}' -

- = ( spasi | komentar )*
spasi = ' ' | '\t' | akhir baris
komentar = '#' ( !akhir baris . )* akhir baris
akhir baris = '\r\n' | '\n' | '\R'
akhir file = !.

MENYESUAIKAN THE PENGurai


Simbol berikut dapat didefinisikan ulang di bagian deklarasi untuk memodifikasi yang dihasilkan
kode pengurai.

YYSTYPE
Jenis nilai semantik. Variabel semu '$$' dan pengidentifikasi 'terikat' ke
hasil aturan dengan operator titik dua ':' semua harus dianggap telah dideklarasikan
untuk memiliki tipe ini. Nilai defaultnya adalah 'int'.

YYPARSE
Nama titik masuk utama ke parser. Nilai defaultnya adalah 'yyparse'.

YYPARSFROM
Nama titik masuk alternatif ke parser. Fungsi ini mengharapkan satu
argumen: fungsi yang sesuai dengan aturan dari mana pencarian kecocokan
harus dimulai. Standarnya adalah 'yyparsefrom'. Perhatikan bahwa yyparse() didefinisikan sebagai

int yyparse() { kembali yyparsefrom(yy_foo); }

di mana 'foo' adalah nama aturan pertama dalam tata bahasa.

YY_INPUT(buf, mengakibatkan, ukuran_maks)
Makro ini dipanggil oleh parser untuk mendapatkan lebih banyak teks input. buf menunjuk ke sebuah
area memori yang dapat menampung paling banyak ukuran_maks karakter. Makro harus menyalin
masukan teks ke buf dan kemudian menetapkan variabel integer mengakibatkan untuk menunjukkan
jumlah karakter yang disalin. Jika tidak ada lagi input yang tersedia, makro harus
tetapkan 0 untuk mengakibatkan. Secara default, makro YY_INPUT didefinisikan sebagai berikut.

#define YY_INPUT(buf, hasil, ukuran_maks) \
{\
int yyc= getchar(); \
hasil= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \
}

Perhatikan bahwa jika YY_CTX_LOCAL didefinisikan (lihat di bawah) maka argumen pertama tambahan,
berisi konteks parser, diteruskan ke YY_INPUT.

YY_DEBUG
Jika simbol ini didefinisikan maka kode tambahan akan dimasukkan dalam parser yang
mencetak sejumlah besar informasi misterius ke kesalahan standar saat parser
sedang berlari.

YY_BEGIN
Makro ini dipanggil untuk menandai awal teks input yang akan tersedia
dalam tindakan sebagai 'yytext'. Ini sesuai dengan kemunculan '<' dalam tata bahasa.
Ini diubah menjadi predikat yang diharapkan berhasil. Standarnya
definisi

#definisikan YY_BEGIN (yybegin= yypos, 1)

oleh karena itu menyimpan posisi input saat ini dan mengembalikan 1 ('benar') sebagai hasil dari
predikat.

YY_END Makro ini sesuai dengan '>' dalam tata bahasa. Sekali lagi, itu adalah predikat jadi
definisi default menyimpan posisi input sebelum 'berhasil'.

#define YY_END (yyend= yypos, 1)

YY_PARSE(T)
Makro ini menyatakan titik masuk parser (yyparse dan yyparsefrom) bertipe
T. Definisi default

#definisikan YY_PARSE(T) T

meninggalkan yyparse() dan yyparsefrom() dengan visibilitas global. Jika mereka tidak seharusnya
terlihat secara eksternal di file sumber lain, makro ini dapat didefinisikan ulang untuk dideklarasikan
mereka 'statis'.

#define YY_PARSE(T) statis T

YY_CTX_LOCAL
Jika simbol ini didefinisikan selama kompilasi parser yang dihasilkan maka global
status parser akan disimpan dalam struktur tipe 'yycontext' yang dapat dideklarasikan
sebagai variabel lokal. Hal ini memungkinkan beberapa contoh parser untuk hidup berdampingan dan untuk
menjadi benang-aman. Fungsi penguraian kamu menguraikan() akan dideklarasikan untuk mengharapkan yang pertama
argumen tipe 'yycontext *', sebuah instance dari struktur yang memegang global
negara untuk parser. Instance ini harus dialokasikan dan diinisialisasi ke nol dengan
klien. Contoh sepele tapi lengkap adalah sebagai berikut.

#termasuk

#tentukan YY_CTX_LOCAL

#include "the-generated-parser.peg.c"

int main ()
{
yykonteks ctx;
memset(&ctx, 0, ukuran(yykonteks));
while (yyparse(&ctx));
0 kembali;
}

Perhatikan bahwa jika simbol ini tidak terdefinisi maka parser yang dikompilasi akan statis
mengalokasikan status globalnya dan tidak akan masuk kembali atau aman untuk thread. Perhatikan juga
bahwa struktur yycontext parser diinisialisasi secara otomatis pertama kali
kamu menguraikan() disebut; struktur ini harus oleh karena itu diinisialisasi dengan benar ke nol
sebelum panggilan pertama ke kamu menguraikan,

YY_CTX_MEMBERS
Jika YY_CTX_LOCAL didefinisikan (lihat di atas) maka makro YY_CTX_MEMBERS dapat ditentukan
untuk memperluas ke deklarasi bidang anggota tambahan apa pun yang diinginkan klien
termasuk dalam deklarasi tipe struktur 'yycontext'. Tambahan ini
anggota sebaliknya diabaikan oleh parser yang dihasilkan. Contoh 'yycontext'
terkait dengan parser yang saat ini aktif tersedia dalam tindakan sebagai
variabel penunjuk yy.

YY_BUFFER_SIZE
Ukuran awal buffer teks, dalam byte. Defaultnya adalah 1024 dan buffernya
ukuran digandakan setiap kali diperlukan untuk memenuhi permintaan selama penguraian. Sebuah aplikasi
yang biasanya mem-parsing string yang lebih panjang dapat meningkatkan ini untuk menghindari yang tidak perlu
realokasi penyangga.

YY_STACK_SIZE
Ukuran awal variabel dan tumpukan tindakan. Standarnya adalah 128, yaitu
dua kali lipat setiap kali diperlukan untuk memenuhi permintaan selama parsing. Aplikasi yang memiliki
tumpukan panggilan dalam dengan banyak variabel lokal, atau yang melakukan banyak tindakan setelah a
satu pertandingan yang berhasil, dapat meningkatkan ini untuk menghindari buffer yang tidak perlu
realokasi.

YY_MALLOC(YY, UKURAN)
Pengalokasi memori untuk semua penyimpanan terkait parser. Parameternya adalah
struktur yycontext saat ini dan jumlah byte yang akan dialokasikan. Standarnya
definisinya adalah: malloc(UKURAN)

YY_REALLOC(YY, PTR, UKURAN)
Realocator memori untuk penyimpanan yang berkembang secara dinamis (seperti buffer teks dan
tumpukan variabel). Parameternya adalah struktur yycontext saat ini,
penyimpanan yang sebelumnya dialokasikan, dan jumlah byte yang harus disimpan oleh penyimpanan tersebut
ditumbuhkan. Definisi defaultnya adalah: realoc(PTR, UKURAN)

YY_GRATIS(YY, PTR)
Deallocator memori. Parameternya adalah struktur yycontext saat ini dan
penyimpanan untuk deallocate. Definisi default adalah: gratis(PTR)

YYRELEASE
Nama fungsi yang melepaskan semua sumber daya yang dipegang oleh struktur yycontext.
Nilai defaultnya adalah 'yyrelease'.

Variabel berikut dapat dirujuk dalam tindakan.

tangki *yybuf
Variabel ini menunjuk ke buffer input parser yang digunakan untuk menyimpan teks input yang memiliki
belum dicocokkan.

int ya
Ini adalah offset (dalam yybuf) dari karakter berikutnya yang akan dicocokkan dan dikonsumsi.

tangki *yyteks
Teks cocok terbaru yang dipisahkan dengan '<' dan '>' disimpan dalam variabel ini.

int yyleng
Variabel ini menunjukkan jumlah karakter dalam 'yytext'.

yykonteks *Y y
Variabel ini menunjuk ke contoh 'yycontext' yang terkait dengan
parser yang sedang aktif.

Program yang ingin melepaskan semua sumber daya yang terkait dengan parser dapat menggunakan
fungsi berikut.

yyrilis(yykonteks*yy)
Mengembalikan semua penyimpanan yang dialokasikan parser yang terkait dengan yy ke sistem. penyimpanan
akan dialokasikan kembali pada panggilan berikutnya ke kamu menguraikan,

Perhatikan bahwa penyimpanan untuk struktur yycontext itu sendiri tidak pernah dialokasikan atau diklaim kembali
secara implisit. Aplikasi harus mengalokasikan struktur ini dalam penyimpanan otomatis, atau gunakan
panggilan() dan gratis() untuk mengelolanya secara eksplisit. Contoh di bagian berikut
menunjukkan satu pendekatan untuk manajemen sumber daya.

LEG CONTOH: MEMPERPANJANG THE PARSER KONTEKS


yy variabel yang diteruskan ke tindakan berisi status pengurai ditambah tambahan apa pun
bidang yang ditentukan oleh YY_CTX_MEMBERS. Bidang ini dapat digunakan untuk menyimpan aplikasi khusus
informasi yang bersifat global untuk panggilan tertentu kamu menguraikan(). Sepele tapi lengkap kaki
contoh berikut di mana struktur yycontext diperpanjang dengan a menghitung dari jumlah
karakter baris baru yang terlihat dalam input sejauh ini (tata bahasa akan dikonsumsi dan diabaikan
seluruh masukan). Penelepon dari kamu menguraikan() menggunakan menghitung untuk mencetak jumlah baris
masukan yang dibaca.

%{
#menentukan YY_CTX_LOCAL 1
#tentukan YY_CTX_MEMBERS \
jumlah int;
%}

Char = ('\n' | '\r\n' | '\r') { yy->hitung++ }
| .

%%

#termasuk
#termasuk

int main ()
{
/* membuat konteks parser lokal di penyimpanan otomatis */
yykonteks yy;
/* konteksnya *harus* diinisialisasi ke nol sebelum digunakan pertama kali*/
memset(&yy, 0, ukuran(yy));

sementara (yyparse(&yy))
;
printf("%d baris baru\n", yy.hitung);

/* lepaskan semua sumber daya yang terkait dengan konteks */
yyrilis(&yy);

0 kembali;
}

DIAGNOSTIK


pasak dan kaki memperingatkan tentang kondisi berikut saat mengubah tata bahasa menjadi parser.

sintaksis kesalahan
Tata bahasa input salah format dalam beberapa cara. Pesan kesalahan akan menyertakan
teks yang akan dicocokkan (sering kali dicadangkan dalam jumlah besar dari lokasi sebenarnya
kesalahan) dan nomor baris karakter yang paling baru dipertimbangkan (yaitu
seringkali lokasi sebenarnya dari masalah).

memerintah 'foo' bekas tapi tidak didefinisikan
Tata bahasa mengacu pada aturan bernama 'foo' tetapi tidak ada definisi yang diberikan.
Mencoba menggunakan pengurai yang dihasilkan kemungkinan akan menghasilkan kesalahan dari tautan
karena simbol yang tidak ditentukan terkait dengan aturan yang hilang.

memerintah 'foo' didefinisikan tapi tidak bekas
Tata bahasa mendefinisikan aturan bernama 'foo' dan kemudian mengabaikannya. Kode terkait
dengan aturan termasuk dalam parser yang dihasilkan yang akan dalam semua hal lainnya
sehat.

mungkin tak terbatas meninggalkan pengulangan in memerintah 'foo'
Terdapat setidaknya satu jalur melalui tata bahasa yang mengarah dari aturan 'foo'
kembali ke (permohonan rekursif dari) aturan yang sama tanpa menggunakan input apa pun.

Rekursi kiri, terutama yang ditemukan dalam dokumen standar, sering 'langsung' dan
menyiratkan pengulangan sepele.

# (6.7.6)
langsung-abstrak-deklarator =
LPAREN abstrak-deklarator RPAREN
| langsung-abstrak-deklarator? LBRACKET menetapkan-expr? RBRACKET
| langsung-abstrak-deklarator? BRACKET BINTANG LBRACKET
| langsung-abstrak-deklarator? Daftar tipe param LPAREN? RPAREN

Rekursi dapat dengan mudah dihilangkan dengan mengubah bagian-bagian dari pola berikut:
rekursi menjadi sufiks berulang.

# (6.7.6)
langsung-abstrak-deklarator =
langsung-abstrak-deklarator-kepala?
langsung-abstrak-deklarator-ekor*

langsung-abstrak-deklarator-head =
LPAREN abstrak-deklarator RPAREN

langsung-abstrak-deklarator-ekor =
LBRACKET menetapkan-expr? RBRACKET
| BRACKET BINTANG LBRACKET
| Daftar tipe param LPAREN? RPAREN

PERINGATAN


Pengurai yang menerima input kosong akan selalu berhasil. Perhatikan contoh berikut,
tidak biasa dari upaya pertama untuk menulis parser berbasis PEG:

Program = Ekspresi*
Ekspresi = "terserah"
%%
int main () {
sementara (yyparse())
puts("berhasil!");
0 kembali;
}

Program ini berulang selamanya, apa pun (jika ada) input yang disediakan di stdin. Banyak
perbaikan dimungkinkan, yang paling mudah adalah bersikeras bahwa parser selalu mengkonsumsi beberapa
masukan tidak kosong. Mengubah baris pertama menjadi

Program = Ekspresi+

menyelesaikan ini. Jika parser diharapkan mengkonsumsi seluruh input, maka secara eksplisit
membutuhkan end-of-file juga sangat disarankan:

Program = Ekspresi+ !.

Ini berfungsi karena parser hanya akan gagal mencocokkan ("!" predikat) karakter apa pun
("." ekspresi) ketika mencoba membaca di luar akhir input.

Gunakan pasak online menggunakan layanan onworks.net


Server & Workstation Gratis

Unduh aplikasi Windows & Linux

  • 1
    Manajer PAC
    Manajer PAC
    PAC adalah pengganti Perl/GTK untuk
    SecureCRT/Putty/dll (linux
    ssh/telnet/... gui)... Ini menyediakan GUI
    untuk mengonfigurasi koneksi: pengguna,
    kata sandi, aturan EXPECT...
    Unduh Manajer PAC
  • 2
    GeoServer
    GeoServer
    GeoServer adalah perangkat lunak sumber terbuka
    server yang ditulis dalam Java yang memungkinkan pengguna
    untuk berbagi dan mengedit data geospasial.
    Dirancang untuk interoperabilitas, itu
    menerbitkan da...
    Unduh GeoServer.dll
  • 3
    Kunang-kunang III
    Kunang-kunang III
    Keuangan pribadi sumber terbuka dan gratis
    Pengelola. Fitur Firefly III a
    sistem pembukuan berpasangan. Kamu bisa
    cepat masuk dan atur
    transaksi saya...
    Unduh Firefly III
  • 4
    Ekstensi Apache OpenOffice
    Ekstensi Apache OpenOffice
    Katalog resmi Apache
    ekstensi OpenOffice. Anda akan menemukan
    ekstensi mulai dari kamus hingga
    alat untuk mengimpor file PDF dan untuk menghubungkan
    dengan ekst...
    Unduh Ekstensi Apache OpenOffice
  • 5
    MantisBT
    MantisBT
    Mantis adalah web yang mudah digunakan
    bugtracker berbasis untuk membantu bug produk
    pelacakan. Ini membutuhkan PHP, MySQL dan a
    server web. Lihat demo dan host kami
    menawarkan...
    Unduh MantisBT
  • 6
    Utusan LAN
    Utusan LAN
    LAN Messenger adalah aplikasi obrolan p2p
    untuk komunikasi intranet dan tidak
    membutuhkan server. Berbagai berguna
    fitur yang didukung termasuk
    pemberitahuan...
    Unduh LAN Messenger
  • Lebih banyak lagi »

Perintah Linux

Ad