Mungkinkah yylval menjadi struct, bukan gabungan?

Di Bison, mungkinkah yylval menjadi struct, bukan union? Saya tahu bahwa saya dapat mendefinisikan yylval sebagai gabungan dengan %union{} tetapi apakah ada cara untuk mendefinisikan yylval sebagai struct? untuk mengembalikan baris dan string pengidentifikasi sebagai contoh dan mengakses informasi ini tentang tindakan beberapa aturan tata bahasa pada bison.


person Joao Pedro    schedule 25.11.2018    source sumber


Jawaban (2)


Ya, Anda dapat #define YYSTYPE menjadi tipe apa pun yang Anda inginkan daripada menggunakan %union. Namun, hal ini jarang berguna1 -- jika Anda menginginkan informasi posisi sumber, sebaiknya gunakan %position yang dikombinasikan dengan %union.

Dimungkinkan juga (dan umum) untuk menggunakan struct dalam deklarasi %union. Hal ini memudahkan beberapa aturan untuk mengembalikan beberapa nilai (secara efektif).


1Masalah utamanya adalah jika Anda menggunakan %type untuk menentukan penggunaan satu bidang struct, akan sulit menggunakan bidang lain dalam tindakan yang sama. Anda perlu melakukan semuanya secara manual, sehingga kehilangan manfaat dari pemeriksaan tipe gabungan bison

person Chris Dodd    schedule 25.11.2018

Jika Anda ingin menyimpan informasi lokasi (nomor baris dan nomor kolom) untuk token Anda, Anda dapat menggunakan fasilitas lokasi Bison, yang menyimpan objek lokasi untuk setiap token dan non-terminal secara terpisah dari nilai semantik. Dalam suatu tindakan, Anda merujuk ke lokasi simbol sebagai @n.

Tumpukan lokasi dibuat dan dipelihara secara otomatis oleh bison jika bison melihat bahwa Anda telah merujuk ke lokasi mana pun dalam suatu aturan.

Secara default, tipe data lokasi adalah:

typedef struct YYLTYPE {
  int first_line;
  int first_column;
  int last_line;
  int last_column;
} YYLTYPE;

Informasi lokasi token harus diatur oleh lexer. Jika Anda menggunakan API default, itu disimpan dalam variabel global yylloc. Parser akan membuat informasi lokasi untuk non-terminal dengan menggunakan rentang dari awal item pertama produksi hingga akhir item terakhir. (Untuk produksi kosong, objek lokasi dengan panjang nol dihasilkan, dimulai dan diakhiri dengan posisi awal token lookahead.)

Kedua default ini dapat ditimpa jika perlu. Lihat panduan Bison untuk mengetahui detailnya.

Flex akan melacak nomor baris jika diminta dengan %option yylineno, tetapi tidak melacak posisi kolom, yang agak mengganggu. Selain itu, yylloc memerlukan nomor baris awal dan akhir; yylineno dalam tindakan fleksibel akan menjadi nomor baris di akhir token. Paling umum, Anda akan menggunakan makro YY_USER_ACTION untuk mempertahankan nilai yylloc; contoh implementasi (diambil dari jawaban ini, yang harus Anda baca jika menggunakan kode ini) adalah:

%option yylineno
%{
#define YY_USER_ACTION                                       \
  yylloc.first_line = yylloc.last_line;                      \
  yylloc.first_column = yylloc.last_column;                  \
  if (yylloc.first_line == yylineno)                         \
     yylloc.last_column += yyleng;                           \
  else {                                                     \
     int col;                                                \
     for (col = 1; yytext[yyleng - col] != '\n'; ++col) {}   \
     yylloc.last_column = col;                               \
     yylloc.last_line = yylineno;                            \
  }
%}
person rici    schedule 26.11.2018
comment
Saya ingin menyimpan yytext dan token integer di yylval, misalnya #define YYSTYPE struct { int token; char *literal };, apakah mungkin? - person linrongbin; 08.01.2020
comment
@linrongbin: Tentu. Namun jangan gunakan #define YYSTYPE; itu pasti akan membuatmu mendapat masalah. Anda perlu memastikan deklarasi tersebut terlihat di mana pun diperlukan, yang berarti deklarasi tersebut harus berada di header yang dibuat oleh bison. Untuk mencapainya, masukkan deklarasi struct (struct MyToken { ... }) ke dalam blok code requires dalam definisi bison Anda, lalu gunakan %define api.value.type {struct MyToken}, seperti yang dijelaskan dalam panduan bison. Jika Anda memerlukan jawaban yang lebih detail, ajukan pertanyaan baru. - person rici; 08.01.2020