2016-12-02 79 views
0

我試圖用yacc/bison語法構造一個比較鏈表。解析大於Bison/Yacc的鏈

總之我概念想拿:

3 < 4 < 5 

,創造我試過的價值,比較等基本鏈表來簡化我現在有具體-IST測試用例

%{ 

#define LESS_THAN 1 

typedef struct mylist { 
    long num; 
    int sym; 
    mylist* next; 
} mylist; 

void destroy_mylist(mylist* l) { 
    mylist* n = NULL; 

    if (l->next != NULL) { 
     n = l->next; 
    } 

    free(l); 

    if (n != NULL) { 
     destroy_mylist(n); 
    } 
} 

mylist* create_list(long left, long right, int sym) { 
    mylist* l = malloc(sizeof(mylist)); 
    mylist* r = malloc(sizeof(mylist)); 
    l->num = left; 
    l->sym = sym; 
    l->next = r; 
    r->num = right; 
    return l; 
} 

mylist* add_list(mylist* l, long num, int sym) { 
    mylist* n = malloc(sizeof(mylist)); 
    mylist* t = l; 
    n->num = num; 

    while (t->next != NULL) { 
     t = t->next; 
    } 

    t->sym = sym; 
    t->next = n; 
    return l; 
} 

%} 
%destructor { destroy_mylist($$); } <list> 

%union { 
    long tmp; 
} 

%type <list> top_list expr compare_chain 
%left '<' 
%token <tmp> T_LONG "Long" 
%start start 

%% /* Rules */ 

start: 
    top_list { $1; } 
; 

top_list: 
    expr { $$ = $1; } 
| { $$ = NULL; } 
; 

expr: 
    compare_chain { $$ = $1; } 
| T_LONG { $$ = $1; } 
; 

compare_chain: 
    compare_chain '<' expr { $$ = add_list($1, $3, LESS_THAN); } 
| expr '<' expr { $$ = create_list($1, $3, LESS_THAN); } 
; 

%% 

FWIW,這可能不會編譯,它試圖成爲我試圖在這裏嘗試的一個緊密的例子。這樣做的目的是,其結果將是一個MYLIST結構將類似於:

1 = {num = 3, sym = 1, next = 2} 
2 = {num = 4, sym = 1, next = 3} 
3 = {num = 5, sym = -, next = null} 

回答

2

add_list功能添加到列表的末尾,但因爲你的yacc規則是正確的遞歸它建立從右側的列表中向左,這意味着你想添加到列表的前面。將其更改爲:

mylist* add_list(mylist* l, long num, int sym) { 
    mylist* n = malloc(sizeof(mylist)); 
    n->num = num; 
    n->sym = sym; 
    n->next = l; 
    return n; 
} 

你也有一個破碎的語法,在expr方面在compare_chaincompare_chain來定義expr。擺脫expr: compare_chain規則,並將top_list更改爲top_list: compare_chain