gnu awk1.01源碼編譯安裝——續

gnu awk1.01源碼編譯安裝——續
這個雙休日又把時間耗在了gawk1.01的編譯安裝了,我原來好象曾編譯過,但當時對代碼的理解不深刻,編譯過後,就沒如何讀代碼了。而且我的機器環境又多,當時好像是在windows下安裝bison,不知如何在ubuntu下編譯成功了。
今天接着開始在ubuntu下安裝。
還是像原來一樣,報了無數的錯誤,因爲根本生成不了可執行程序,於是,我就把gcc進行降級安裝,還是不行。
後來,歸結到bison編譯不了。
於是,我單獨把bison的編譯拿出來。
bison -v awk.y
發現報了一堆錯誤。網上百度,對移進是歸約錯誤,也沒有人回答。
我總是想,這個程序,作者肯定曾編譯過的,不然,作者不會發布。因爲,我總是想,應該不需要對awk.y的語法進行修改,只是加某個選項,就能順利編譯的。網上有人說,對awk.output文件進行分析,我打開一看,果然有一堆錯誤。
於是就逐個分析。

State 2 conflicts: 1 shift/reduce
State 23 conflicts: 3 shift/reduce
State 33 conflicts: 1 shift/reduce
State 42 conflicts: 2 shift/reduce
State 44 conflicts: 2 shift/reduce
State 76 conflicts: 19 shift/reduce
State 104 conflicts: 1 shift/reduce
State 107 conflicts: 2 shift/reduce
State 112 conflicts: 1 shift/reduce
State 129 conflicts: 19 shift/reduce
State 136 conflicts: 1 shift/reduce
State 147 conflicts: 2 shift/reduce
State 148 conflicts: 2 shift/reduce
State 156 conflicts: 2 shift/reduce
State 168 conflicts: 1 shift/reduce
State 174 conflicts: 2 shift/reduce
State 175 conflicts: 2 shift/reduce
State 176 conflicts: 2 shift/reduce
State 182 conflicts: 2 shift/reduce
我把這個歸約衝突彙總起來,恰好等於make時報的shift/reduce錯誤總數。
網上找不到資料,於是就讀書《flex and bison》,書上發現有一個選項

%glr-parser
%expect 67
其中那個67是來自於移進歸約的衝突總數。
然後就總算生成了awk.y的編譯文件。但其它的程序編譯時,總是不斷的報錯。
象使用bcopy,bzero等過期函數的問題,象函數沒有先定義,就使用的問題,象缺乏相關庫函數的問題,像NULL重複定義的問題,等等。
有一段時間,我甚至想,重新把庫函數的定義也複製一份放在源代碼中,因爲包含庫的話,有時會引起衝突,而且作者用了一個obstack.h,obstack.c這兩個文件來實現malloc,free之類功能,而我包含stdlib.h後,裏面也有malloc,free這兩個函數,就有衝突了,後來,我乾脆就把obstack.h中,自帶的malloc,free禁用。
改動的地方太多,我想,或許把修改後的源碼放上去較好。
最終,總算,編譯出gawk可執行程序了。
但一執行
./gawk --version
就報錯:
yang@DESKTOP-V9HS3B6:~/gawk101/gawk$ ./gawk --version
./gawk: Segmentation fault (core dumped)
因爲我是在win10下應用商站中安裝ubuntu,我實驗過,沒法生成core文件,我又卡住了。於是,心想,不是還有幾百個編譯警告嗎,於是,把這些警告信息全部去掉,或許可以執行呢。於是又開始折騰,其中一個最有名的警告是:
obstack.h中有
struct obstack          /* control current object in current chunk */
{
  long  chunk_size;             /* preferred size to allocate chunks in */
  _Ll*  chunk;                  /* address of current struct obstack_chunk */
  char  *object_base;           /* address of object we are building */
  char  *next_free;             /* where to add next char to current object */
  char  *chunk_limit;           /* address of char after current chunk */
  unsigned long long int        temp;                   /* Temporary for some macros.  */
  int   alignment_mask;         /* Mask of alignment for each object. */
};
其中temp原來是int型,
#define obstack_finish(h)                                               \
 ((h)->temp = (unsigned long long int ) (h)->object_base,
上面把一個指針傳爲整數後,存儲到temp中,而我的系統是win10
64位系統,存儲一個指針是8位。於是寫了幾個測試程序,如下:
yang@DESKTOP-V9HS3B6:~/gawk101$ cat t4.c
#include<stdio.h>
int main()
{
        int i;
        printf("%p\n",&i);
        unsigned long long dizi=&i;
        printf("%lld,%p\n",dizi,dizi);
        return 0;
}

yang@DESKTOP-V9HS3B6:~/gawk101$ cat t5.c
#include<stdio.h>
int main()
{
        unsigned long long int i=100;
        printf("%lld\n",i);
        printf("%llx\n",i);
        return 0;
}
於是,就把temp由int改爲unsigned long long int,這樣,就好了。
還有許多。逐一去掉後。再一執行
./gawk --version
還是錯誤。後來,我腦洞大開,是否我沒有--version選項,果然。我再試下。
 ./gawk
./gawk: usage: ./gawk {-f progfile | program } [-F{c} -R{c}] file . . .
yang@DESKTOP-V9HS3B6:~/gawk101/gawk$ echo "hello world" | ./gawk '$1 ~ /ll/'
hello world
可稍複雜的例子,就報錯了:
yang@DESKTOP-V9HS3B6:~/gawk101/gawk$ echo "hello world" | ./gawk '{print $0 }'
Ambiguity detected.
Option 1,
  statements -> <Rule 24, tokens 2 .. 5>
    statements -> <Rule 22, empty>
    statement -> <Rule 41, tokens 2 .. 5>
      LEX_PRINT <tokens 2 .. 2>
      $@3 -> <Rule 40, empty>
      expression_list -> <Rule 59, tokens 3 .. 4>
        exp -> <Rule 69, tokens 3 .. 4>
          variable -> <Rule 98, tokens 3 .. 4>
            '$' <tokens 3 .. 3>
            v_exp -> <Rule 88, tokens 4 .. 4>
              NUMBER <tokens 4 .. 4>
      redirection -> <Rule 54, empty>
      statement_term -> <Rule 25, tokens 5 .. 5>
        NEWLINE <tokens 5 .. 5>
        optional_newlines -> <Rule 52, empty>

Option 2,
  statements -> <Rule 23, tokens 2 .. 5>
    statement -> <Rule 41, tokens 2 .. 5>
      LEX_PRINT <tokens 2 .. 2>
      $@3 -> <Rule 40, empty>
      expression_list -> <Rule 59, tokens 3 .. 4>
        exp -> <Rule 69, tokens 3 .. 4>
          variable -> <Rule 98, tokens 3 .. 4>
            '$' <tokens 3 .. 3>
            v_exp -> <Rule 88, tokens 4 .. 4>
              NUMBER <tokens 4 .. 4>
      redirection -> <Rule 54, empty>
      statement_term -> <Rule 25, tokens 5 .. 5>
        NEWLINE <tokens 5 .. 5>
        optional_newlines -> <Rule 52, empty>

Error near line 1,  '{print $0 }'
syntax is ambiguous
yang@DESKTOP-V9HS3B6:~/gawk101/gawk$
天啦,看來,還是我要對bison進行深入的學習,前面加了glr分析選項,是讓其可以繼續分析下去,但衝突終究是存在的。可惜的是,我看不懂這個衝突呀,我怎麼看,好像都沒有衝突的樣子。
網上找資源,其中有一位翻譯了bison中文操作手冊,但也沒有速成辦法。還是要對awk.y進行深入分析。我想用高一版本的gawk中,awk.y的內容進行替換,但發現gawk2中,awk.y的內容就完全不相同了。
這些大師爲何會對awk.y進行如此大修改呢。
真的,我發現編譯老版本程序太麻煩,真想放棄算了,直接讀高版本代碼不是更好嗎。但下載了gawk最新版本的源程序,安裝起來,真是無比順暢,可一打開源碼,太多了,和gawk1.01比起來,多了不少。心想,我看gawk1.01都這麼熟悉了,還是看1.01吧。於是,又接着分析bison,心想,別人都能寫出來,我難道還看不出來嗎。
另外,英語不懂,就安裝必應翻譯後,把obstack.h改爲obstack.txt,在翻譯軟件中打開文件後,一邊讀翻譯後的內容,一邊讀源碼。
發現,C語言的問題好解決,但bison的問題不好解決。
本來,想,自己這半瓶水,就不寫博客了,但心想,反正是自己看着玩的,還是寫下來吧。今天要上班,也不能花太多時間去讀源碼。
我這回有了成功編譯gawk1.01的經驗,下次估計真能把ruby049也搞成功。
我還是堅信,讀最老版本的源碼,收穫大於讀最新版本的程序。因爲讀老版本程序,會有一種大局觀,而讀新版本的程序,量太大,你只能就某個細節進行學習,你沒時間,也沒能力把全部源碼讀通。
而一旦對程序有一種大局觀後,我就不怕了。麻雀雖小,五臟俱全呀。繼續努力!

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章