2009-05-20 25 views
6

Tôi đang viết một ngữ pháp trong YACC (thực sự là Bison), và tôi đang gặp vấn đề về ca/​​giảm. Nó kết quả từ bao gồm các toán tử tăng và tăng hậu tố. Dưới đây là một phiên bản cắt giảm của ngữ pháp:Làm cách nào để sửa YACC shift/giảm xung đột từ toán tử tăng sau?

%token NUMBER ID INC DEC 

%left  '+' '-' 
%left  '*' '/' 
%right  PREINC 
%left  POSTINC 

%% 

expr: NUMBER 
|  ID 
|  expr '+' expr 
|  expr '-' expr 
|  expr '*' expr 
|  expr '/' expr 
|  INC expr %prec PREINC 
|  DEC expr %prec PREINC 
|  expr INC %prec POSTINC 
|  expr DEC %prec POSTINC 
|  '(' expr ')' 
; 

%% 

Bison nói với tôi có 12 ca/​​giảm xung đột, nhưng nếu tôi nhận xét ra các dòng cho increment postfix và sụt lần, nó hoạt động tốt. Có ai biết cách khắc phục xung đột này không? Tại thời điểm này, tôi đang xem xét việc chuyển sang trình tạo phân tích cú pháp LL (k), điều này làm cho nó dễ dàng hơn nhiều, nhưng các ngữ pháp LALR luôn có vẻ tự nhiên hơn nhiều khi viết. Tôi cũng đang xem xét GLR, nhưng tôi không biết về bất kỳ trình tạo phân tích cú pháp C/C++ GLR nào tốt.

+3

Tôi sẽ đánh giá cao nếu các cử tri ít nhất sẽ đưa ra lý do ... – Zifre

Trả lời

3

Bison/Yacc có thể tạo trình phân tích cú pháp GLR nếu bạn chỉ định %glr-parser trong phần tùy chọn.

+0

Wow! Tôi không biết điều đó ... Tôi đã thử nó, nhưng tôi vẫn nhận được những xung đột giảm dần với ngữ pháp gốc của mình. Tôi đoán rằng thuật toán GLR của Bison không hợp tác với ưu tiên tốt, nhưng điều này có thể làm việc kết hợp với câu trả lời của David Dolson. – Zifre

+0

Được rồi, tôi vừa thử phương pháp này với phương pháp của David Dolson, và nó hoạt động! – Zifre

+1

-1: Sử dụng chế độ GLR không phải là một giải pháp tốt cho điều này, vì bạn vẫn cần giải quyết sự mơ hồ bằng cách nào đó, và, điều tồi tệ hơn, nếu bạn KHÔNG sửa chữa sự mơ hồ, bison sẽ âm thầm chấp nhận ngữ pháp mà không có khiếu nại, và đưa ra các lỗi thời gian chạy của bạn thay vào đó, vì vậy bạn có thể dễ dàng nghĩ rằng bạn đã khắc phục được sự cố khi bạn không có. –

0

Tôi muốn xác định thêm mục. Bạn không nên cần% left,% right,% prec stuff.

simple_expr: NUMBER 
| INC simple_expr 
| DEC simple_expr 
| '(' expr ')' 
; 

term: simple_expr 
| term '*' simple_expr 
| term '/' simple_expr 
; 

expr: term 
| expr '+' term 
| expr '-' term 
; 

Phát xung quanh với phương pháp này.

+1

Tôi đã thử cách tiếp cận đó trước đây và tôi không thích nó. Khi bạn có nhiều ngữ pháp biểu thức phức tạp hơn (như đối với C++), sẽ khó hiểu chính xác những gì bạn phải làm nếu bạn muốn sửa đổi nó. Sử dụng ưu tiên sạch hơn, IMO. – Zifre

2

Hãy thử điều này:

%token NUMBER ID INC DEC 

%left  '+' '-' 
%left  '*' '/' 
%nonassoc '++' '--' 
%left  '(' 
%% 

expr: NUMBER 
|  ID 
|  expr '+' expr 
|  expr '-' expr 
|  expr '*' expr 
|  expr '/' expr 
|  '++' expr 
|  '--' expr 
|  expr '++' 
|  expr '--' 
|  '(' expr ')' 
; 

%% 

Điều quan trọng là phải tuyên bố khai thác postfix như phi kết. Nếu không, bạn sẽ có thể

++var++-- 

Các ngoặc cũng cần phải nhận được một ưu tiên để giảm thiểu sự thay đổi/giảm cảnh báo

+0

Trên thực tế, vì hành vi C bình thường bạn muốn '++ var ++' để phân tích cú pháp là '+ + (var ++)' và không bị từ chối dưới dạng lỗi (postfix cao hơn tiền tố), bạn muốn '% right' không'% nonassoc' –

+0

Ngoài ra, ưu tiên cho ''('' là vô nghĩa vì không có xung đột liên quan đến nó ở đây. Bạn sẽ cần nó nếu có xung đột (ví dụ, nếu bạn thêm lệnh gọi hàm C hoặc kiểu cú pháp), nhưng trường hợp đó bạn có thể muốn '% right' không'% left' –

-1

preincrement và postincrement nhà khai thác có nonassoc để xác định rằng trong phần ưu tiên và trong các quy tắc làm các ưu tiên của các toán tử cao bằng cách sử dụng %prec

0

vấn đề cơ bản này là bạn không có một ưu tiên cho INCDEC thẻ, vì vậy nó không biết làm thế nào để giải quyết sự mơ hồ liên quan đến một lookahead của INC hoặc DEC. Nếu bạn thêm

%right INC DEC 

vào cuối danh sách ưu tiên (bạn muốn unaries là ưu tiên cao hơn và postfix cao hơn tiền tố), nó sẽ sửa chữa nó, và bạn thậm chí có thể thoát khỏi tất cả những thứ PREINC/POSTINC , vì nó không liên quan.

Các vấn đề liên quan