2016-12-02 53 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