cuốn sách gpt4 ai đã làm

c - Giá trị in Bison/Flex cho thiết bị đầu cuối thay thế

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 01:03:06 25 4
mua khóa gpt4 Nike

Tôi đã viết một cú pháp đơn giản:

hoạt động:
/* trống */
| hoạt động hoạt động ';'
| hoạt động hoạt động_id ';'
;

hoạt động:
NUM toán tử NUM
{
printf("%d\n%d\n",$1, $3);
}
;

hoạt động_id:
Toán tử WORD WORD
{
printf("%s\n%s\n%s\n",$1, $3, $2);
}
;

toán tử:
'+' | '-' | '*' |
{
$$ = strdup(yytext);
}
;

Như bạn có thể thấy, tôi đã xác định một toán tử để xác định một trong 4 biểu tượng. Bây giờ tôi muốn vào hoạt động_id In ký hiệu này ở định dạng . Vấn đề là,toán tử Logic chỉ áp dụng cho ký hiệu cuối cùng thay thế. Vì vậy nếu tôi viết a/b;, nó sẽ in ra ab/, thật tuyệt. Nhưng đối với các hoạt động khác, ví dụ. a+b; nó inaba. Tôi đã làm gì sai?

*Tôi đã bỏ qua ký hiệu dòng mới trong ví dụ đầu ra.

câu trả lời hay nhất

Cú pháp không đầu cuối này trong cú pháp của bạn là hoàn toàn sai.

toán tử:
'+' | '-' | '*' | '/' { $$ = strdup(yytext }
;

Đầu tiên, trong yacc/bison, mọi hoạt động sản xuất đều có một Hành động. Quy tắc này có bốn sản phẩm, chỉ sản phẩm cuối cùng có Hành động liên quan. Sẽ rõ ràng hơn nếu viết nó theo cách này:

toán tử: '+' 
|
|
| '/' { $$ = strdup(yytext }
;

Điều này làm cho thao tác chỉ khả dụng đối với mã thông báo '/' Sự giảm bớt rõ ràng hơn. .

Bản thân hành động cũng không chính xác. văn bản yykhông nên ở đó lexer hoạt động, vì giá trị của nó không đáng tin cậy; nó sẽ là giá trị khi thao tác từ vựng gần đây nhất được thực hiện, nhưng vì trình phân tích cú pháp thường (nhưng không phải luôn luôn) đọc mã thông báo trước thời hạn, nên nó thường (nhưng không phải luôn luôn như vậy) Mã thông báo tiếp theo. Đó là lý do tại sao lời khuyên thông thường là hãy sao chép văn bản yy lý do. , nhưng ý tưởng là sao chép nóTrong quy tắc lexer, gán một bản sao cho yylval Các thành viên phù hợp để trình phân tích cú pháp có thể sử dụng giá trị ngữ nghĩa của mã thông báo.

Bạn nên tránh sử dụng $$ = .Một thiết bị không phải thiết bị đầu cuối chỉ có thể có một loại và nó phải được khai báo trong phần mở đầu của tệp bison:

 Toán tử %type 

Cuối cùng, bạn sẽ thấy hiếm khi hữu ích khi có một nonterminal nhận dạng các toán tử khác nhau vì các toán tử khác nhau có cú pháp khác nhau. Trong cú pháp biểu thức đầy đủ hơn, bạn cần phân biệt a + b * c , là tổng của tích của a nhân với b và c, và a*b+c , là tổng của c nhân với a và b. Điều này có thể được thực hiện bằng cách sử dụng các số không kết thúc khác nhau cho cú pháp tổng và tích hoặc bằng cách sử dụng các kết quả khác nhau cho các biểu thức không kết thúc và sử dụng quy tắc ưu tiên để phân biệt, nhưng trong cả hai trường hợp, bạn không thể sử dụng toán tử. sản xuất + của thiết bị đầu cuối và *bừa bãi.

Về giá trị của nó, đây là lý do tại sao a+bkết quả đầu ra aba :

  1. 制作toán tử: '+'Không có hành động rõ ràng nên cuối cùng nó sử dụng hành động mặc định, đó là $$ = $1 .

  2. Tuy nhiên, trở lại '+' Quy tắc từ vựng cho (có lẽ - tôi đoán ở đây) không bao giờ được đặt yylval .Vì thếyylvalVẫn có giá trị được gán cuối cùng.

  3. Có lẽ (một cách phỏng đoán khác), tạo ra TỪ Các quy tắc lexer được đặt chính xác yylval.string = strdup(yytext); .Vì thế '+' Giá trị ngữ nghĩa của mã thông báo là trướcTỪGiá trị ngữ nghĩa của mã thông báo là nó trỏ đến một chuỗi "a" con trỏ.

  4. Vì vậy khi các quy định

    hoạt động_id:
    Toán tử WORD WORD
    {
    printf("%s\n%s\n%s\n",$1, $3, $2);
    }
    ;

thực hiện,$1$2Giá trị của cả hai là "a" (hai con trỏ tới cùng một chuỗi) và$3có giá trị "b" .

rõ ràng,$2 về mặt ngữ nghĩa là không chính xác để có giá trị "a" , nhưng có một lỗi khác đang chờ xảy ra. Như đã viết, trình phân tích cú pháp của bạn rò rỉ bộ nhớ vì bạn không bao giờ miễn phí() sự căng thẳng Bất kỳ chuỗi nào được tạo ra đều không thỏa mãn và đến một lúc nào đó bạn sẽ muốn sửa các thao tác này để chúng được giải phóng khi các giá trị ngữ nghĩa không còn cần thiết nữa. Lúc đó bạn sẽ thấy rất có thể có hai giá trị ngữ nghĩa trỏ đến cùng một khối bộ nhớ được cấp phát miễn phí()sẽ được gọi hai lần trên cùng một khối bộ nhớ, đây là hành vi không xác định (và có thể tạo ra các lỗi rất khó chẩn đoán).

Về giá trị in Bison/Flex trong C - Alternative Terminal, chúng tôi tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/30742906/

25 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress