簡體   English   中英

建立野牛語法時,終端上顯示了太多無用的規則

[英]too many useless rules show up on terminal while building a bison grammar

編碼:

%{
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "gener.h"
#include "sym_tab.h"
#include "scope.h"
#include "defs.h"
extern char *yytext;
#define YYPRINT(file, type, value)   yyprint (file, type, value)
%}

%union
{
char *name;
char idtype;
decl_list idlist;
/*decl_list is in gener.h,  
  you should #include "gener.h"
*/
}

%token PROGRAM
%token IDENTIFIER 
%token DECIMAL_CONSTANT
%token DECLARE ENDDECLARE

%token AND CALL DEFAULT
%token FUNCTION PROCEDURE IN INOUT
%token IF ELSE DO WHILE FOR OR NOT SELECT
%token RETURN EXIT  PRINT 
%token EQ_LT EQ_GT NE EXACT 
%left '+' '-'
%right '*' '/'



%start program
%%

program
        : %empty
        | PROGRAM IDENTIFIER block
        ;

block
        : "{" declarations subprograms sequence "}"
        ;
declarations
        : %empty
        | DECLARE varlist ENDDECLARE 
        ;
varlist
        : %empty
        | assignment_stat identifier2
        ;

identifier2 : ',' assignment_stat
        | ',' assignment_stat 

        ;
subprograms 
        : func
        | subprograms ','  
        ;
func        
        : PROCEDURE IDENTIFIER funcbody
        | FUNCTION IDENTIFIER funcbody
        ;
funcbody    
        : formalpars block
        ;
formalpars  
        : '('')'
        | '(' formalparlist ')'

        ;
formalparlist   
        : formalparitem
        | formalparlist ','

        ;
formalparitem   
        : IN IDENTIFIER
        | INOUT IDENTIFIER
        ;       
sequence
        : statement statement_sequence
        ;
statement_sequence
        : ";"statement
        | ';' statement statement_sequence
        ;
brackets_seq    
        : '{' sequence '}'
        ;
brack_or_stat   
        : brackets_seq
        | statement
        ;


statement   
        : %empty
        | assignment_stat
        | if_stat
        | do_while_stat
        | while_stat
        | select_stat
        | exit_stat
        | return_stat
        | print_stat
        | call_stat
        ;
assignment_stat
            : IDENTIFIER EXACT IDENTIFIER 
            ;

if_stat
        : IF '(' condition')' brack_or_stat elsepart
        ;
elsepart
        : %empty
        | ELSE brack_or_stat
        ;
while_stat
        : WHILE '(' condition')' brack_or_stat
        ;
select_stat
        : SELECT'(' IDENTIFIER')'
          dec 
          DEFAULT":" brack_or_stat
        ;
dec
        : DECIMAL_CONSTANT ':' brack_or_stat
        | dec ','
        ;
do_while_stat
        : DO brack_or_stat WHILE '(' condition ')'
        ;
exit_stat   
        : EXIT
        ;
return_stat
        : RETURN '(' expression ')'
        ;
print_stat
        : PRINT '('expression ')'
        ;
call_stat
        : CALL IDENTIFIER actualpars
        ;
actualpars
        : '('')'
        | '('actualparlist')'
        ;
actualparlist
        : actualparitem 
        | actualparlist ','
        ;
actualparitem
        : IN expression
        | INOUT IDENTIFIER
        ;
condition
        : boolterm or_boolterm 
        ;
or_boolterm 
        : OR boolterm
        | OR boolterm or_boolterm
        ;
boolterm    
        : boolfactor and_boolfactor
        ;
and_boolfactor
        : AND boolfactor
        | AND boolfactor and_boolfactor
        ;
boolfactor  
        : NOT '[' condition ']'
        | '[' condition ']'
        | expression relational_oper expression
        ;
expression
        : optional_sign term add_oper_term
        ;
add_oper_term
        : add_oper term
        | add_oper term add_oper_term
        ;
term        
        : factor mul_oper_factor
        ;
mul_oper_factor
        : mul_oper factor 
        | mul_oper factor mul_oper_factor
        ;
factor
        : DECIMAL_CONSTANT
        | expression
        | IDENTIFIER idtail
        ;
idtail
        : %empty
        | actualpars
        ;
relational_oper
        : '='
        | '<'
        | "<="
        | "<>"
        | ">="
        | '>'
        ;
add_oper
        : '+'
        | '-'
        ;
mul_oper
        : '*'
        | '/'
        ;
optional_sign
        : add_oper
        | %empty
        ;



%%

這是我為野牛創建的語法,但是當我在終端上嘗試野​​牛gram.y時,會出現一堆警告。 試圖切換他們被寫的順序,但我仍然得到同樣的東西這里是終端輸出

gram.y: warning: 44 nonterminals useless in grammar [-Wother]
gram.y: warning: 86 rules useless in grammar [-Wother]
gram.y:43.38-42: warning: nonterminal useless in grammar: block [-Wother]
        | PROGRAM IDENTIFIER block
                                      ^^^^^
gram.y:47.23-34: warning: nonterminal useless in grammar: declarations [-Wother]
        : "{" declarations subprograms sequence "}"
                       ^^^^^^^^^^^^
gram.y:51.27-33: warning: nonterminal useless in grammar: varlist [-Wother]
        | DECLARE varlist ENDDECLARE 
                           ^^^^^^^
gram.y:55.35-45: warning: nonterminal useless in grammar: identifier2 [-Wother]
        | assignment_stat identifier2
                                   ^^^^^^^^^^^
gram.y:47.36-46: warning: nonterminal useless in grammar: subprograms [-Wother]
        : "{" declarations subprograms sequence "}"
                                    ^^^^^^^^^^^
gram.y:63.19-22: warning: nonterminal useless in grammar: func [-Wother]
        : func
                   ^^^^
gram.y:67.40-47: warning: nonterminal useless in grammar: funcbody [-Wother]
        : PROCEDURE IDENTIFIER funcbody
                                        ^^^^^^^^
gram.y:71.19-28: warning: nonterminal useless in grammar: formalpars [-Wother]
        : formalpars block
                   ^^^^^^^^^^
gram.y:75.23-35: warning: nonterminal useless in grammar: formalparlist [-Wother]
        | '(' formalparlist ')'
                       ^^^^^^^^^^^^^
gram.y:79.19-31: warning: nonterminal useless in grammar: formalparitem [-Wother]
        : formalparitem
                   ^^^^^^^^^^^^^
gram.y:47.48-55: warning: nonterminal useless in grammar: sequence [-Wother]
        : "{" declarations subprograms sequence "}"
                                                ^^^^^^^^
gram.y:88.29-46: warning: nonterminal useless in grammar: statement_sequence [-Wother]
        : statement statement_sequence
                             ^^^^^^^^^^^^^^^^^^
gram.y:94.1-12: warning: nonterminal useless in grammar: brackets_seq [-Wother]
 brackets_seq   
 ^^^^^^^^^^^^
gram.y:97.1-13: warning: nonterminal useless in grammar: brack_or_stat [-Wother]
 brack_or_stat  
 ^^^^^^^^^^^^^
gram.y:88.19-27: warning: nonterminal useless in grammar: statement [-Wother]
        : statement statement_sequence
                   ^^^^^^^^^
gram.y:55.19-33: warning: nonterminal useless in grammar: assignment_stat [-Wother]
        | assignment_stat identifier2
                   ^^^^^^^^^^^^^^^
gram.y:106.19-25: warning: nonterminal useless in grammar: if_stat [-Wother]
        | if_stat
                   ^^^^^^^
gram.y:120.53-60: warning: nonterminal useless in grammar: elsepart [-Wother]
        : IF '(' condition')' brack_or_stat elsepart
                                                     ^^^^^^^^
gram.y:108.19-28: warning: nonterminal useless in grammar: while_stat [-Wother]
        | while_stat
                   ^^^^^^^^^^
gram.y:109.19-29: warning: nonterminal useless in grammar: select_stat [-Wother]
        | select_stat
                   ^^^^^^^^^^^
gram.y:131.19-21: warning: nonterminal useless in grammar: dec [-Wother]
          dec 
                   ^^^
gram.y:107.19-31: warning: nonterminal useless in grammar: do_while_stat [-Wother]
        | do_while_stat
                   ^^^^^^^^^^^^^
gram.y:110.19-27: warning: nonterminal useless in grammar: exit_stat [-Wother]
        | exit_stat
                   ^^^^^^^^^
gram.y:111.19-29: warning: nonterminal useless in grammar: return_stat [-Wother]
        | return_stat
                   ^^^^^^^^^^^
gram.y:112.19-28: warning: nonterminal useless in grammar: print_stat [-Wother]
        | print_stat
                   ^^^^^^^^^^
gram.y:113.19-27: warning: nonterminal useless in grammar: call_stat [-Wother]
        | call_stat
                   ^^^^^^^^^
gram.y:151.35-44: warning: nonterminal useless in grammar: actualpars [-Wother]
        : CALL IDENTIFIER actualpars
                                   ^^^^^^^^^^
gram.y:155.22-34: warning: nonterminal useless in grammar: actualparlist [-Wother]
        | '('actualparlist')'
                      ^^^^^^^^^^^^^
gram.y:158.19-31: warning: nonterminal useless in grammar: actualparitem [-Wother]
        : actualparitem 
                   ^^^^^^^^^^^^^
gram.y:120.26-34: warning: nonterminal useless in grammar: condition [-Wother]
        : IF '(' condition')' brack_or_stat elsepart
                          ^^^^^^^^^
gram.y:166.28-38: warning: nonterminal useless in grammar: or_boolterm [-Wother]
        : boolterm or_boolterm 
                            ^^^^^^^^^^^
gram.y:166.19-26: warning: nonterminal useless in grammar: boolterm [-Wother]
        : boolterm or_boolterm 
                   ^^^^^^^^
gram.y:173.30-43: warning: nonterminal useless in grammar: and_boolfactor [-Wother]
        : boolfactor and_boolfactor
                              ^^^^^^^^^^^^^^
gram.y:173.19-28: warning: nonterminal useless in grammar: boolfactor [-Wother]
        : boolfactor and_boolfactor
                   ^^^^^^^^^^
gram.y:145.30-39: warning: nonterminal useless in grammar: expression [-Wother]
        : RETURN '(' expression ')'
                              ^^^^^^^^^^
gram.y:185.38-50: warning: nonterminal useless in grammar: add_oper_term [-Wother]
        : optional_sign term add_oper_term
                                      ^^^^^^^^^^^^^
gram.y:185.33-36: warning: nonterminal useless in grammar: term [-Wother]
        : optional_sign term add_oper_term
                                 ^^^^
gram.y:192.26-40: warning: nonterminal useless in grammar: mul_oper_factor [-Wother]
        : factor mul_oper_factor
                          ^^^^^^^^^^^^^^^
gram.y:192.19-24: warning: nonterminal useless in grammar: factor [-Wother]
        : factor mul_oper_factor
                   ^^^^^^
gram.y:201.30-35: warning: nonterminal useless in grammar: idtail [-Wother]
        | IDENTIFIER idtail
                              ^^^^^^
gram.y:182.30-44: warning: nonterminal useless in grammar: relational_oper [-Wother]
        | expression relational_oper expression
                              ^^^^^^^^^^^^^^^
gram.y:188.19-26: warning: nonterminal useless in grammar: add_oper [-Wother]
        : add_oper term
                   ^^^^^^^^
gram.y:195.19-26: warning: nonterminal useless in grammar: mul_oper [-Wother]
        : mul_oper factor mul_oper_factor
                   ^^^^^^^^
gram.y:185.19-31: warning: nonterminal useless in grammar: optional_sign [-Wother]
        : optional_sign term add_oper_term
                   ^^^^^^^^^^^^^
gram.y:43.19-42: warning: rule useless in grammar [-Wother]
        | PROGRAM IDENTIFIER block
                   ^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:47.19-59: warning: rule useless in grammar [-Wother]
        : "{" declarations subprograms sequence "}"
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:50.19-24: warning: rule useless in grammar [-Wother]
        : %empty
                   ^^^^^^
gram.y:51.19-44: warning: rule useless in grammar [-Wother]
        | DECLARE varlist ENDDECLARE 
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:54.19-24: warning: rule useless in grammar [-Wother]
        : %empty
                   ^^^^^^
gram.y:55.19-45: warning: rule useless in grammar [-Wother]
        | assignment_stat identifier2
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:58.19-37: warning: rule useless in grammar [-Wother]
 identifier2    : ',' assignment_stat
                   ^^^^^^^^^^^^^^^^^^^
gram.y:59.19-37: warning: rule useless in grammar [-Wother]
        | ',' assignment_stat 
                   ^^^^^^^^^^^^^^^^^^^
gram.y:63.19-22: warning: rule useless in grammar [-Wother]
        : func
                   ^^^^
gram.y:64.19-33: warning: rule useless in grammar [-Wother]
        | subprograms ','  
                   ^^^^^^^^^^^^^^^
gram.y:67.19-47: warning: rule useless in grammar [-Wother]
        : PROCEDURE IDENTIFIER funcbody
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:68.19-46: warning: rule useless in grammar [-Wother]
        | FUNCTION IDENTIFIER funcbody
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:71.19-34: warning: rule useless in grammar [-Wother]
        : formalpars block
                   ^^^^^^^^^^^^^^^^
gram.y:74.19-24: warning: rule useless in grammar [-Wother]
        : '('')'
                   ^^^^^^
gram.y:75.19-39: warning: rule useless in grammar [-Wother]
        | '(' formalparlist ')'
                   ^^^^^^^^^^^^^^^^^^^^^
gram.y:79.19-31: warning: rule useless in grammar [-Wother]
        : formalparitem
                   ^^^^^^^^^^^^^
gram.y:80.19-35: warning: rule useless in grammar [-Wother]
        | formalparlist ','
                   ^^^^^^^^^^^^^^^^^
gram.y:84.19-31: warning: rule useless in grammar [-Wother]
        : IN IDENTIFIER
                   ^^^^^^^^^^^^^
gram.y:85.19-34: warning: rule useless in grammar [-Wother]
        | INOUT IDENTIFIER
                   ^^^^^^^^^^^^^^^^
gram.y:88.19-46: warning: rule useless in grammar [-Wother]
        : statement statement_sequence
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:91.19-30: warning: rule useless in grammar [-Wother]
        : ";"statement
                   ^^^^^^^^^^^^
gram.y:92.19-50: warning: rule useless in grammar [-Wother]
        | ';' statement statement_sequence
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:95.19-34: warning: rule useless in grammar [-Wother]
        : '{' sequence '}'
                   ^^^^^^^^^^^^^^^^
gram.y:98.19-30: warning: rule useless in grammar [-Wother]
        : brackets_seq
                   ^^^^^^^^^^^^
gram.y:99.19-27: warning: rule useless in grammar [-Wother]
        | statement
                   ^^^^^^^^^
gram.y:104.19-24: warning: rule useless in grammar [-Wother]
        : %empty
                   ^^^^^^
gram.y:105.19-33: warning: rule useless in grammar [-Wother]
        | assignment_stat
                   ^^^^^^^^^^^^^^^
gram.y:106.19-25: warning: rule useless in grammar [-Wother]
        | if_stat
                   ^^^^^^^
gram.y:107.19-31: warning: rule useless in grammar [-Wother]
        | do_while_stat
                   ^^^^^^^^^^^^^
gram.y:108.19-28: warning: rule useless in grammar [-Wother]
        | while_stat
                   ^^^^^^^^^^
gram.y:109.19-29: warning: rule useless in grammar [-Wother]
        | select_stat
                   ^^^^^^^^^^^
gram.y:110.19-27: warning: rule useless in grammar [-Wother]
        | exit_stat
                   ^^^^^^^^^
gram.y:111.19-29: warning: rule useless in grammar [-Wother]
        | return_stat
                   ^^^^^^^^^^^
gram.y:112.19-28: warning: rule useless in grammar [-Wother]
        | print_stat
                   ^^^^^^^^^^
gram.y:113.19-27: warning: rule useless in grammar [-Wother]
        | call_stat
                   ^^^^^^^^^
gram.y:116.19-45: warning: rule useless in grammar [-Wother]
            : IDENTIFIER EXACT IDENTIFIER 
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:120.19-60: warning: rule useless in grammar [-Wother]
        : IF '(' condition')' brack_or_stat elsepart
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:123.19-24: warning: rule useless in grammar [-Wother]
        : %empty
                   ^^^^^^
gram.y:124.19-36: warning: rule useless in grammar [-Wother]
        | ELSE brack_or_stat
                   ^^^^^^^^^^^^^^^^^^
gram.y:127.19-54: warning: rule useless in grammar [-Wother]
        : WHILE '(' condition')' brack_or_stat
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:130.19-132.42: warning: rule useless in grammar [-Wother]
        : SELECT'(' IDENTIFIER')'
                   ^^^^^^^^^
gram.y:135.19-52: warning: rule useless in grammar [-Wother]
        : DECIMAL_CONSTANT ':' brack_or_stat
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:136.19-25: warning: rule useless in grammar [-Wother]
        | dec ','
                   ^^^^^^^
gram.y:139.19-58: warning: rule useless in grammar [-Wother]
        : DO brack_or_stat WHILE '(' condition ')'
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:142.19-22: warning: rule useless in grammar [-Wother]
        : EXIT
                   ^^^^
gram.y:145.19-43: warning: rule useless in grammar [-Wother]
        : RETURN '(' expression ')'
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:148.19-41: warning: rule useless in grammar [-Wother]
        : PRINT '('expression ')'
                   ^^^^^^^^^^^^^^^^^^^^^^^
gram.y:151.19-44: warning: rule useless in grammar [-Wother]
        : CALL IDENTIFIER actualpars
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:154.19-24: warning: rule useless in grammar [-Wother]
        : '('')'
                   ^^^^^^
gram.y:155.19-37: warning: rule useless in grammar [-Wother]
        | '('actualparlist')'
                   ^^^^^^^^^^^^^^^^^^^
gram.y:158.19-31: warning: rule useless in grammar [-Wother]
        : actualparitem 
                   ^^^^^^^^^^^^^
gram.y:159.19-35: warning: rule useless in grammar [-Wother]
        | actualparlist ','
                   ^^^^^^^^^^^^^^^^^
gram.y:162.19-31: warning: rule useless in grammar [-Wother]
        : IN expression
                   ^^^^^^^^^^^^^
gram.y:163.19-34: warning: rule useless in grammar [-Wother]
        | INOUT IDENTIFIER
                   ^^^^^^^^^^^^^^^^
gram.y:166.19-38: warning: rule useless in grammar [-Wother]
        : boolterm or_boolterm 
                   ^^^^^^^^^^^^^^^^^^^^
gram.y:169.19-29: warning: rule useless in grammar [-Wother]
        : OR boolterm
                   ^^^^^^^^^^^
gram.y:170.19-41: warning: rule useless in grammar [-Wother]
        | OR boolterm or_boolterm
                   ^^^^^^^^^^^^^^^^^^^^^^^
gram.y:173.19-43: warning: rule useless in grammar [-Wother]
        : boolfactor and_boolfactor
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:176.19-32: warning: rule useless in grammar [-Wother]
        : AND boolfactor
                   ^^^^^^^^^^^^^^
gram.y:177.19-47: warning: rule useless in grammar [-Wother]
        | AND boolfactor and_boolfactor
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:180.19-39: warning: rule useless in grammar [-Wother]
        : NOT '[' condition ']'
                   ^^^^^^^^^^^^^^^^^^^^^
gram.y:181.19-35: warning: rule useless in grammar [-Wother]
        | '[' condition ']'
                   ^^^^^^^^^^^^^^^^^
gram.y:182.19-55: warning: rule useless in grammar [-Wother]
        | expression relational_oper expression
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:185.19-50: warning: rule useless in grammar [-Wother]
        : optional_sign term add_oper_term
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:188.19-31: warning: rule useless in grammar [-Wother]
        : add_oper term
                   ^^^^^^^^^^^^^
gram.y:189.19-45: warning: rule useless in grammar [-Wother]
        | add_oper term add_oper_term
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:192.19-40: warning: rule useless in grammar [-Wother]
        : factor mul_oper_factor
                   ^^^^^^^^^^^^^^^^^^^^^^
gram.y:195.19-49: warning: rule useless in grammar [-Wother]
        : mul_oper factor mul_oper_factor
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gram.y:196.19-33: warning: rule useless in grammar [-Wother]
        | mul_oper factor 
                   ^^^^^^^^^^^^^^^
gram.y:199.19-34: warning: rule useless in grammar [-Wother]
        : DECIMAL_CONSTANT
                   ^^^^^^^^^^^^^^^^
gram.y:200.19-28: warning: rule useless in grammar [-Wother]
        | expression
                   ^^^^^^^^^^
gram.y:201.19-35: warning: rule useless in grammar [-Wother]
        | IDENTIFIER idtail
                   ^^^^^^^^^^^^^^^^^
gram.y:204.19-24: warning: rule useless in grammar [-Wother]
        : %empty
                   ^^^^^^
gram.y:205.19-28: warning: rule useless in grammar [-Wother]
        | actualpars
                   ^^^^^^^^^^
gram.y:208.19-21: warning: rule useless in grammar [-Wother]
        : '='
                   ^^^
gram.y:209.19-21: warning: rule useless in grammar [-Wother]
        | '<'
                   ^^^
gram.y:210.19-22: warning: rule useless in grammar [-Wother]
        | "<="
                   ^^^^
gram.y:211.19-22: warning: rule useless in grammar [-Wother]
        | "<>"
                   ^^^^
gram.y:212.19-22: warning: rule useless in grammar [-Wother]
        | ">="
                   ^^^^
gram.y:213.19-21: warning: rule useless in grammar [-Wother]
        | '>'
                   ^^^
gram.y:216.19-21: warning: rule useless in grammar [-Wother]
        : '+'
                   ^^^
gram.y:217.19-21: warning: rule useless in grammar [-Wother]
        | '-'
                   ^^^
gram.y:220.19-21: warning: rule useless in grammar [-Wother]
        : '*'
                   ^^^
gram.y:221.19-21: warning: rule useless in grammar [-Wother]
        | '/'
                   ^^^
gram.y:224.19-26: warning: rule useless in grammar [-Wother]
        : add_oper
                   ^^^^^^^^
gram.y:225.19-24: warning: rule useless in grammar [-Wother]
        | %empty
                   ^^^^^^

能幫我嗎?

問題是您生產的subprograms

但是,這對於您(以及可能偶然發現此問題和答案的任何同學)了解如何自行發現此類問題可能更有用。

StackOverflow鼓勵您提供一個“最小,完整和可驗證的示例”(MCVE) ,您應該花一點時間閱讀該幫助頁面。 要求不是因為我們喜歡讓有疑問的人生活困難。 這是因為將問題減少到最低程度是調試的關鍵部分,並且您會發現,隨着習慣的發展,發現問題的能力越來越強。 當然,由於它消除了所有不相關的噪音,它還可以幫助嘗試解決問題的任何人。

但是MCVE不僅很小。 它也是完整的 :也就是說,這實際上是一個問題的摘錄。 僅僅說“我認為問題就在這里,所以我將僅演示這一部分”是不夠的。 您必須通過創建最少的示例並證明確實會產生相同的問題,來證明問題出在哪里。

實際上,如果您牢記這一策略,則將以不同的方式編寫程序。 您無需編寫一千行代碼,然后將其全部輸入到編譯器中,而是將編寫一些獨立的部分並檢查每個部分,然后再將它們組合為一個整體。 這樣,當您無法解決特定問題時,就已經擁有MCVE。

語法令人討厭地相互聯系,並且不像人們所希望的程序那樣模塊化。 一個生產中的少量更改會產生移位減少沖突,涉及另一個看似完全無關的生產。 但是,您通常可以將語法分成或多或少的獨立部分。 例如,您可以僅從定義表達式的語法部分開始:

%token PROGRAM
%token IDENTIFIER 
%token DECIMAL_CONSTANT
%token DECLARE ENDDECLARE

%token AND CALL DEFAULT
%token FUNCTION PROCEDURE IN INOUT
%token IF ELSE DO WHILE FOR OR NOT SELECT
%token RETURN EXIT  PRINT 
%token EQ_LT EQ_GT NE EXACT 
%left '+' '-'
%right '*' '/'

%%

expression
        : optional_sign term add_oper_term
        ;
add_oper_term
        : add_oper term
        | add_oper term add_oper_term
        ;
term        
        : factor mul_oper_factor
        ;
mul_oper_factor
        : mul_oper factor 
        | mul_oper factor mul_oper_factor
        ;
factor
        : DECIMAL_CONSTANT
        | expression
        | IDENTIFIER idtail
        ;
idtail
        : %empty
        | actualpars
        ;
add_oper
        : '+'
        | '-'
        ;
mul_oper
        : '*'
        | '/'
        ;
optional_sign
        : add_oper
        | %empty
        ;

actualpars
        : '('')'
        | '('actualparlist')'
        ;
actualparlist
        : actualparitem 
        | actualparlist ','
        ;
actualparitem
        : IN expression
        | INOUT IDENTIFIER
        ;

這就產生了許多移位/減少沖突,您將必須解決這些沖突,但是卻沒有任何無用的產生。 (請注意,我將所有%token聲明留在了適當的位置,因此上述內容並不是簡單。Bison不在乎是否聲明了您從未使用過的終端,因此將聲明保留在以后的步驟中會更容易)

向上移動一步,我們可以添加condition ,其中涉及添加:

condition
        : boolterm or_boolterm 
        ;
or_boolterm 
        : OR boolterm
        | OR boolterm or_boolterm
        ;
boolterm    
        : boolfactor and_boolfactor
        ;
and_boolfactor
        : AND boolfactor
        | AND boolfactor and_boolfactor
        ;
boolfactor  
        : NOT '[' condition ']'
        | '[' condition ']'
        | expression relational_oper expression
        ;
relational_oper
        : '='
        | '<'
        | "<="
        | "<>"
        | ">="
        | '>'
        ;

現在有更多的移位/減少沖突,但仍然沒有無用的非終結符。

下一步將添加語句產生。 在這里,我們會發現許多語句使用了非終結brack_or_stat ,它的定義如下:

brack_or_stat   
    : brackets_seq
    | statement
    ;   

為了避免再次處理brackets_seq ,我們可以將其臨時添加到終端列表中。 (這是隱藏語法細節的標准技術。)稍后,當我們包含brackets_seq ,我們可以刪除%token聲明。)因此,我們現在添加

%token brackets_seq

before the `%%`, and the statement productions after it:

brack_or_stat   
        : brackets_seq
        | statement
        ;

statement   
        : %empty
        | assignment_stat
        | if_stat
        | do_while_stat
        | while_stat
        | select_stat
        | exit_stat
        | return_stat
        | print_stat
        | call_stat
        ;
assignment_stat
            : IDENTIFIER EXACT IDENTIFIER 
            ;

if_stat
        : IF '(' condition')' brack_or_stat elsepart
        ;
elsepart
        : %empty
        | ELSE brack_or_stat
        ;
while_stat
        : WHILE '(' condition')' brack_or_stat
        ;
select_stat
        : SELECT'(' IDENTIFIER')'
          dec 
          DEFAULT":" brack_or_stat
        ;
dec
        : DECIMAL_CONSTANT ':' brack_or_stat
        | dec ','
        ;
do_while_stat
        : DO brack_or_stat WHILE '(' condition ')'
        ;
exit_stat   
        : EXIT
        ;
return_stat
        : RETURN '(' expression ')'
        ;
print_stat
        : PRINT '('expression ')'
        ;
call_stat
        : CALL IDENTIFIER actualpars
        ;

現在有更多的移位/減少沖突,但是沒有無用的非終結符。

因此,現在我們已經研究了一半以上的語法,並且有把握地確信問題不在我們所研究的部分中。 (盡管還有很多其他問題需要解決。)

因此,如果我們假設該statement還可以,那么將其設為終端,然后從測試中刪除該引用以及它引用的所有非終端。 這給我們留下了一個簡單得多的程序:(當我復制並粘貼此摘錄並通過野牛運行時,它通知我未定義assignment_stat 。因此,我將其添加到%token聲明中。)

%token PROGRAM
%token IDENTIFIER 
%token DECIMAL_CONSTANT
%token DECLARE ENDDECLARE

%token AND CALL DEFAULT
%token FUNCTION PROCEDURE IN INOUT
%token IF ELSE DO WHILE FOR OR NOT SELECT
%token RETURN EXIT  PRINT 
%token EQ_LT EQ_GT NE EXACT 

%token statement assignment_stat

%start program
%%

program
        : %empty
        | PROGRAM IDENTIFIER block
        ;

block
        : "{" declarations subprograms sequence "}"
        ;
declarations
        : %empty
        | DECLARE varlist ENDDECLARE 
        ;
varlist
        : %empty
        | assignment_stat identifier2
        ;

identifier2 : ',' assignment_stat
        | ',' assignment_stat 

        ;
subprograms 
        : func
        | subprograms ','  
        ;
func        
        : PROCEDURE IDENTIFIER funcbody
        | FUNCTION IDENTIFIER funcbody
        ;
funcbody    
        : formalpars block
        ;
formalpars  
        : '('')'
        | '(' formalparlist ')'

        ;
formalparlist   
        : formalparitem
        | formalparlist ','

        ;
formalparitem   
        : IN IDENTIFIER
        | INOUT IDENTIFIER
        ;       
sequence
        : statement statement_sequence
        ;
statement_sequence
        : ";"statement
        | ';' statement statement_sequence
        ;
brackets_seq    
        : '{' sequence '}'
        ;
brack_or_stat   
        : brackets_seq
        | statement
        ;

現在,我們有一個充滿“無用的非終端”警告的屏幕。

但是,語法現在要簡單得多。 (如果看起來不夠簡單,則可以繼續進行簡化操作。例如,一種可能性是分離聲明。)確實,問題可能很明顯:

subprograms 
        : func
        | subprograms ','  
func    : PROCEDURE IDENTIFIER funcbody
        | FUNCTION IDENTIFIER funcbody
funcbody: formalpars block
block: "{" declarations subprograms sequence "}"

注意這里發生了什么: subprograms有兩個生成。 第二個顯然是遞歸的。 但是,只需花很少的工作就可以看到另一個也是遞歸的: func有兩個產品,但是都使用funcbody funcbody的唯一產品使用block ,而block使用subprograms

因此, subprograms沒有非遞歸產生,因此它永遠不會脫離遞歸。 而且funcfuncbodyblock都不能。

但是,如果block無法生成任何語句,則program的第二個產生式( PROGRAM IDENTIFIER block )也無法生成任何語句,從而使program: %empty成為起始符號的唯一有效產生。 這使空字符串成為唯一有效的program ,因此,野牛將所有其他非終端標記為無用。

現在,讓我們回到subprograms (正如我剛開始所說的那樣,這是當前的問題)。 定義是:

subprograms 
        : func
        | subprograms ','  

現在,這是一個非常奇怪的定義(我認為,整個語法中都會重復出現這種奇怪的現象)。 這是在說什么 subprograms是一個func或一個subprograms后跟一個逗號。 因此它將產生:

func
func ,
func , ,
func , , ,
func , , , ,

等等。 單個func ,后跟零個或多個逗號。 必須具有一個func,而不能具有更多。

它不能為空的事實是無限遞歸的原因。 block必須包含一個subprograms ,並且一個subprograms必須包含一個func func必須包含一個block 從那個旋轉木馬也無法逃脫。

因此,這里存在兩個問題: subprograms不能為空,也不能包含多個func 您可能正在尋找的是:

function_list: func
             | function_list ',' func
subprograms  : %empty
             | function_list

請注意, function_list使用左遞歸。 那是故意的。 野牛產生LR解析器,它喜歡左遞歸。

如果您以前學習過LL解析器,卻以某種方式使它陷入困境,那么左遞歸就是邪惡的, 那就不要上那課了 LL解析器無法處理左遞歸,但是LR解析器可以處理左遞歸和右遞歸,並且可以更好地處理左遞歸(因為它不會耗盡解析器堆棧)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM