當前位置:首頁 » 編程軟體 » 編譯原理一個晚上學完

編譯原理一個晚上學完

發布時間: 2022-07-05 23:58:50

1. 操作系統,匯編語言,編譯原理,這三門課程學習步驟是什麼 以及原因,求詳細解釋,非常感謝。

匯編語言、編譯原理、操作系統吧

1.首先編譯原理肯定要在匯編之後學的,你不會匯編編什麼譯
2.匯編語言肯定講的是實模式的內容,學完了實模式對計算機內程序有個基本概念了,研究保護模式的時候就要涉及到操作系統了
3.至於編譯原理我沒學過,姑且認為應該也是實模式的內容吧,所以放到操作系統之前學習

2. 編譯原理學了有什麼用

對大多數人來說,學過編譯原理,應該可以知道對於很多代碼的優化,編譯器其實可以做好,不需要自己寫代碼的時候杞人憂天。在通用、局部的優化上,甚至編譯器往往做得比程序員好。

大概率會意識到編譯原理背後的故事,也許會沉迷在某個方向,也許還會樂於看一些奇妙的parser構建方式。

大概還可能會去學習類型系統,發現形式化的故事似乎在很多方面都有對應的版本,而後,他們也許會嘗試走向研究,去挑戰目前都沒有好好解決的代碼優化問題,也許會走向應用,用起LLVM,在上面加個target,支持一些新硬體,做個新語言的前端等。

編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程序構造的一般原理和基本方法。內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成。 編譯原理是計算機專業設置的一門重要的專業課程。

編譯原理課程是計算機相關專業學生的必修課程和高等學校培養計算機專業人才的基礎及核心課程,同時也是計算機專業課程中最難及最挑戰學習能力的課程之一。編譯原理課程內容主要是原理性質,高度抽象。

編譯可以分為五個基本步驟:詞法分析、語法分析、語義分析及中間代碼的生成、優化、目標代碼的生成。這是每個編譯器都必須的基本步驟和流程, 從源頭輸入高級語言源程序輸出目標語言代碼。

1、詞法分析

詞法分析器是通過詞法分析程序對構成源程序的字元串從左到右的掃描, 逐個字元地讀, 識別出每個單詞符號, 識別出的符號一般以二元式形式輸出, 即包含符號種類的編碼和該符號的值。

詞法分析器一般以函數的形式存在, 供語法分析器調用。當然也可以一個獨立的詞法分析器程序存在。完成詞法分析任務的程序稱為詞法分析程序或詞法分析器或掃描器。

2、語法分析

語法分析是編譯過程的第二個階段。這階段的任務是在詞法分析的基礎上將識別出的單詞符號序列組合成各類語法短語, 如「語句」, 「表達式」等.語法分析程序的主要步驟是判斷源程序語句是否符合定義的語法規則, 在語法結構上是否正確。

而一個語法規則又稱為文法, 喬姆斯基將文法根據施加不同的限制分為0型、1型、2型、3型文法, 0型文法又稱短語文法, 1型稱為上下文有關文法, 2型稱為上下文無關文法, 3型文法稱為正規文法, 限制條件依次遞增。

3、語義分析

詞法分析注重的是每個單詞是否合法, 以及這個單詞屬於語言中的哪些部分。語法分析的上下文無關文法注重的是輸入語句是否可以依據文法匹配產生式。

那麼, 語義分析就是要了解各個語法單位之間的關系是否合法。實際應用中就是對結構上正確的源程序進行上下文有關性質的審查, 進行類型審查等。

4、中間代碼生成與優化

在進行了語法分析和語義分析階段的工作之後, 有的編譯程序將源程序變成一種內部表示形式, 這種內部表示形式叫做中間語言或中間表示或中間代碼。

所謂「中間代碼」是一種結構簡單、含義明確的記號系統, 這種記號系統復雜性介於源程序語言和機器語言之間, 容易將它翻譯成目標代碼。另外, 還可以在中間代碼一級進行與機器無關的優化。

5、目標代碼的生成

根據優化後的中間代碼, 可生成有效的目標代碼。而通常編譯器將其翻譯為匯編代碼, 此時還需要將匯編代碼經匯編器匯編為目標機器的機器語言。

6、出錯處理

編譯的各個階段都有可能發現源碼中的錯誤, 尤其是語法分析階段可能會發現大量的錯誤, 因此編譯器需要做出錯處理, 報告錯誤類型及錯誤位置等信息。

3. 剛學完編譯原理,想看看在編譯層面c++是怎麼實現的,有什麼好的書籍...

C++ Primer Plus
C++ Primer

4. 學習編譯原理和操作系統對編程能力有什麼作用

學習編譯原理和操作系統對編程能力對編程能力的作用在於:

1、學好了編譯原理,才可能編寫出高效,穩健,佔用內存少的程序。

2、學習操作系統對windows相關的編程很有幫助。如果是對操作系統關系不大的C/C++/c#,java之類的編程,關系不大。

編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程序構造的一般原理和基本方法。內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成。 編譯原理是計算機專業設置的一門重要的專業課程。雖然只有少數人從事編譯方面的工作,但是這門課在理論、技術、方法上都對學生提供了系統而有效的訓練,有利於提高軟體人員的素質和能力。

操作系統(Operating System,簡稱OS)是管理和控制計算機硬體與軟體資源的計算機程序,是直接運行在「裸機」上的最基本的系統軟體,任何其他軟體都必須在操作系統的支持下才能運行。

5. 學完編譯原理能幹什麼

試著寫寫編譯器吧,會有收獲的~~~

6. 學完了c語言,是否有必要學Java

看完這個,你可能會有自己的一點想法了
應屆生學C好還是學JAVA好,做什麼更掙錢
老師:
你好。
我是一名09界剛畢業工作不久的java菜鳥級程序員。本人對java水平可以混口飯了,現在可以在工作中開發一般的小項目,都是B/S的。 本人基礎很爛,基本上:演算法 、數據結構、計算機組成原理、操作系統、編譯原理可以說從來沒有學過。目前我工作的環境是:開發b/s 架構的項目,不考慮性能,實際上實現需求就可以了。我可以跟客戶打交道,可以自己分析需求,可以自己跟其他人合作一些10萬以下的小項目。基本上都是對資料庫的增刪改查。來來去去都是那些表非常無聊。
雖然工作不久,但是目前已經感覺到在這樣下去,頂多隻是熟悉一下業務而言。就本身編程水平基本上沒多少提高。因為公司追求效益,只要寫出來的東西能用就完事,沒時間考慮代碼,而且java沒有指針,也不用的演算法,工作中的設計模式也就常用的幾個。剩下的幾乎沒什麼可以提高的了( 項目管理學了一些,已經其他 )。
目前非常希望轉C方面發展,我C語言可以認為0水平。但是由於有了java功底。雖然已經體會到語言只不過是解決方案的工具而已。但是就算我在java裡面花再多時間感覺自己只是在浪費青春,我絕不是小看java,因為我也是用這門語言的,java沒有內存管理,用java或者類似的語言,我永遠只看到上層的東西。我希望自己成為一名技術非常強悍的程序員。可以寫出一些經典的開源工具。因為以前大學都是逃課,睡覺,打游戲。所以基礎很差,實際上我相當於一個0基礎的高中生學了半年java的人。目前自己每天在學數據結構。但是不知道路在哪裡。我想換一份 C 的工作,不知道從哪裡開始學。我選C有幾個原因的:C的工作環境可以迫使你使用演算法,然後進一步的慢慢深入,可以接觸操作系統,然後慢慢使自己進入高層次的開發。因為C涉及面廣,所以迫使自己學得到很多東西。進而提升自己水平而已。與其說選C語言,不如所選C語言所涉及的范圍而已!因為在java環境,不可能到達我理想高度!
大環境很浮躁,這是我切身的體會。但是我有耐心和毅力。我第一步的想法是 先轉到涉及演算法的環境。實在不行,只要開發上用到C就行了。 因為我對C的工作環境不了解,可能理解上有誤,希望你指點一下。如果像我這種水平的人,想要找到C的工作,大概怎麼起步。 我說一下自己的java起步 當初我是這樣的: 1、學習java 語法(j2se)。
2、用java 做一個 俄羅斯游戲。 3、學習 jsp 做一個MVC的留言板, 學習 流行框架(SSH), 做一個 管理系統。
就這樣 我就找到 JAVA EE 應用開發的工作了。當時進公司不用適應期就直接上項目了。

我當初是在沒有老師( 老師重來不把一個年年補考,每次都墊底的學生當人看),同學鄙視(最後一個學期每個人都找工作,打游戲。而我每天都在瘋狂的學習 一直到畢業前夕 ),沒有人管的情況下過來的。靠google, , 買經典教材,網路視頻,Q群 的情況下,終於用一張合同在畢業前證明了自己的能力! 這段辛酸的經歷給了我很多東西,特別是自製力、自學能力、毅力。

現在我已經打算辭職回家,再次進入瘋狂的學習狀態,雖然現在每天下班回來也在學習。但是每天4個小時遠遠比不上 原先每天12個小時的自學效率。而且自學可以連續學半年,現在每天還要工作,非常不合適。
我希望用半年 至少補上 大學的 數據結構,基本演算法,計算機組成原理,操作系統、 同時復習數學知識( 主要是 離散數學、線性代數 )這些基礎。 如果半年內時間緊的 Linux、匯編和編譯原理可否先暫時緩緩。

工作意向:優先 游戲編程, 然後其他的用C的也可以( 曾經非常想考慮 C的嵌入式,但是發現涉及知識有點廣,而且工具也不便宜 )其實我非常希望向網路發展,只是不知道代價多大( TCP/IP 和其它網路知識不懂,這個要多久,1個月內可以達到工作要求可以接受 )。

然而C的路子怎麼走呢?
原先這樣思考的 : 1 C語法 2、用一個小游戲( 俄羅斯方塊、或者是 五指棋 )來鞏固前面C語言基本知識。 掌握這些後我不知道幹嘛了。
第三步:????( MFC? 不學它行不行,如果工作普遍需要我非常樂意學 )

目前本人的水平基本(資質普通)就這樣了。你看通過半年 每天12個小時的高強度的學習,怎麼才可以到達目前 找到 使用 C語言 開發 的工作。 希望您指點一下。最好可以列出來幾條路子 , 比如 游戲編程的、網路的、然後其它的。
非常感謝你看完我的郵件, 靜候佳音。
2009-10-12

專家回答:

這位同學你好,從這封信看得出來你的心情還是很急迫的,你這種心情我完全能夠理解。我把問題分幾點說,盡量說細一點,希望能對你有所幫助。

首先,你說你是09年畢業的大學生,那麼算下來,你應該上班才幾個月而已,就這一點,你能在新的單位幾個月時間就把工作拿上手,首先恭喜你,這說明你是真的很有實力,當年我轉行游戲編程,用了差不多兩年才真正想清楚程序設計的真意,我覺得你比我強。呵呵。

你說Java基本上都是做B/S資料庫,覺得沒有意思,其實這個我也很理解,不過,我覺得你可能不是很了解實際情況。這里我需要給你講清楚,其實不僅僅是Java程序員,只要到企業中做應用開發,或多或少都和資料庫沾點邊。當年我用VC還寫報表系統呢,你能說這不是資料庫?

其實有個問題可能大家都沒有關注到,至少,我到學生大本營半年,發現大家都沒有討論過。那就是,做什麼最賺錢?無可否認,軟體可以實現各方面應用,不過,就我的觀察,在現實生活中,有兩種軟體最賺錢,一種是資料庫,一種就是嵌入式底層的東東,嗯,隨著互聯網的發展,目前做網路程序也很賺錢。

其實原因很簡單,就是因為軟體的盜版問題。我想看到我這篇文章的每個人,或多或少都用過盜版軟體,包括我自己,呵呵,咱們中國人窮啊,動輒幾百上千的軟體費用,咱們買不起的,所以電腦城的光碟市場才這么火爆。

但是,這帶來了另外一個問題,就是當有一天,我們自己成為軟體開發者的時候,才發現,盜版導致我們自己的收入降低,無法維系生活。這時候,恐怕再來大聲疾呼,杜絕盜版,已經晚了,你說是不?

其實我們可能對市場不敏感,反正每個月發薪水,收入基本上旱澇保收,但是公司的老總們對這個很敏感,軟體賣不出錢,公司就虧本,虧多了,就垮掉了,最終程序員還是沒有收入。

因此,公司裡面做軟體,一般都做上面的軟體,即資料庫應用,嵌入式應用,控制類應用,網路服務應用較多。因為這幾種應用,不容易被盜版,能賣到錢。通用性的應用,比如操作系統,比如很多工具軟體,比如PC游戲,其實很難賣錢的。

資料庫應用,一般資料庫本身是使用成熟的商用系統,如MySQL,SQL Server,Oracle等,我們小公司拿來,再根據具體應用需求,做二次定製開發,這是一大類市場,其實這個市場的真正名字叫做「企業數據應用定製市場」。由於是定製的,自然沒有通用性,也就不會有盜版了。

控制類,嵌入式類,很多都和具體硬體設備相關,換個硬體平台就不通用了,大家知道,中國的東東,要防盜版,最好和硬體相關,只要綁定硬體,軟體一般不好到,以前出的防病毒卡,漢卡什麼的,其實利用的就是這個市場規律。

服務應用呢,就更好說了,由於主要程序邏輯都在伺服器端,基於B/S的模型,客戶端連個軟體都沒有,伺服器的管理自然比賣出去的軟體好管理,不容易盜版。因此,這類企業也活得長,比如各個網站,各種網游什麼的。所以我一直覺得,以後雲計算發展起來後,很多軟體可能會把零售制改為租用制,比如photoshop,大家買套軟體幾千,但一般人就是處理一下自家照片,自然不劃算,因此盜版很多,但以後假如軟體公司把它做成伺服器版,大家把照片上傳,處理,最後再存回來,這個過程每次租金1毛錢,每個人都花得起的話,我看以後就沒那麼多盜版了。另外,伺服器應用其實大多數也是資料庫應用。

所以,我首先要說,不管你是不是換工作,以後你恐怕會一直遇到資料庫類的應用,不管你喜歡不喜歡,但這是社會的現實,你必須承認。你說對吧?

在這個共識下,我們再來看,其實我們會發現,三大主流應用中,只有嵌入式不適合Java,其他的資料庫和伺服器應用,其實Java比C和C++方便得多,因此,我建議你就在Java這條路上走下去,不一定非要轉C和C++。本來你的強項就是Java,而且這也是主流的可以賣錢的市場,為啥不堅持呢?

從另外一個角度說,我也認為你應該堅持,你畢竟畢業不到半年,對社會,對公司,對本職工作其實了解並不深入,你認為Java就那麼幾個設計模式,沒有挑戰性,這個我能理解,但是,我覺得你說的不全面。起碼我做程序做了這么多年,到底有多少種設計模式,我也說不清楚,我相信很多人都說不清楚。需要具體應用具體分析。

我不是Java程序員,不過我覺得,如果要做一個合格的程序員,首先不應該是程序設計的大師,而應該是理解客戶需求,並迅速拿出解決方案的專家,這個,不管用什麼語言,不管在哪裡工作,都是必須的,同時,這也需要很長時間的積累。

准確的講,我認為,一個人不在一門語言,一種業務領域努力3年、5年乃至10年,是很難成為專家的。因此,我建議你完全沒有必要這山望著那山高,輕易就決定跳槽,建議你就這個環境,先鍛煉自己,我這里放句話,你可以試著驗證一下,兩三年以後,你再看Java語言和資料庫開發,都還是會找到自己不會,值得學習和鑽研的東西的。因為最起碼,客戶的需求是千變萬化,永無止境的。

當然,話分兩說,如果你真的喜歡C,很想做嵌入式應用,就是不想做Java,那也無可厚非,因為畢竟每個人都有選擇的權利。

不過,我仍然不建議你辭職回家學習。我以前有句話,大學畢業,才是學習的開始,不過,這個大學畢業後的學習,和學校中的學習,有很大差別,突出的幾點:沒有老師,沒有教材,都是自己主動學,針對自己的需求來學習,學技巧多,學原理少,並且一般都是干中學,而不是學完了再干,我總結就是「用以致學」,而不是「學以致用」,這是我總結的學習經驗。

同時,畢業了,總不好意思再向家裡面父母要錢,總得自己賺錢養活自己。你說是吧?你說辭職半年,專心學習,那你沒有收入吃啥?還不是吃父母的?這樣不是很好。

C語言沒有那麼神聖的,也沒有太高的門檻的,不要想太復雜了。另外,指針,內存什麼的,學習C語言確實能接觸到,但是,我還是要說,C語言並不是因為有了指針和內存的直接訪問,才牛叉,C語言是因為大量的程序員用它解決了很多具體應用,才牛叉的。請你注意不要學偏了,不要為學指針而學指針。指針就是指針,僅僅是個訪問工具而已,不是用來顯得很酷的,需要了才用它。

Java語言用個數組,其實也能模擬指針的大部分功能的。其實我作為C程序員,我們平時工作時對指針是很謹慎的,能不用都不用,盡量用引用來代替,為啥,因為危險,容易出錯。

數據結構,計算機組成原理,演算法語言,編譯原理,嗯,還有個圖論,這幾門應該算最經典的計算機理論了,但是,也沒那麼神秘的,書店裡面有,自己沒事買幾本回來看看就好了,生活是沒有考試的,不需要你必須考夠100分才能找到工作,了解,理解就好了,背書是背不出好程序員的。你說對吧?

其實這幾門,不用C和C++語言,用Java語言一樣可以學習的。嗯,編譯原理可能夠嗆,需要理解一點C。

另外,我再給你透露一點點,其實真正實際應用中,我們對於上述基礎知識用得很少,用得最多的,其實就是數據結構裡面的隊列了,其他,包括棧都很少用,C程序員也不是每天都從底層,從0做起的,還是有很多工具套用的。這和Java語言從框架開發是一個道理。

反而有一門課程建議你好好學,就是概率和統計學,這門知識是我現在應用最多的,很多時候,我們評估軟體系統性能,瓶頸優化,都是在用這個學問。程序員做久了,可能大多數時候都是和這個在打交道,建議買本好好看。

總結一下吧,建議你目前暫時不要辭職,既然選擇了Java和資料庫應用開發,選擇了B/S模型,你耐心做3年再看,也許3年後,你自己的想法就變了。

C可以學,你說的課程都可以學,不過,不要辭職專門學,先賺錢養活自己,再利用時間學習,你這么大的決心,每天晚上就不要看電視了,那你每天晚上,19:00~24:00,至少有5個小時來學習,利用好了,我敢說比你在大學裡面效率高。

看書學習不是什麼神秘,神聖的事情的,也不需要什麼齋戒沐浴,念幾天經才能學習,我覺得就和我們吃飯喝水一樣,隨時都可以學的,找幾本書,就在床頭放著,每天晚上看看,幾個月也就看完了,又有多難嘛?

關鍵是,養成習慣。

你說對不?呵呵,先說到這里,有問題再問哈。

最後補充一點,如果學習C,並且有一定基礎的話,等我書出來看看吧,裡面的跨平台開發工程庫,可以幫助你迅速掌握嵌入式底層的一些技巧。不過,要有基礎哈,一點不會C看不明白的。

7. 編譯原理究竟有沒有用對編程的人

我跟你說,編譯原理太有用了。
我是做手機游戲的,現在做一個游戲引擎。既然是引擎,就需要提供抽象的東西給上層使用。這里,我引入了腳本系統。
這個腳本系統包括一堆我根據實際需求自行設計的指令集,包括基本的輸入輸出,四則運算,系統功能調用,函數聲明,調用等等(其實你要是用過lua或者其他游戲腳本你就知道了。)整個結構包括指令集、編譯器、虛擬機等部分。這樣,引擎提供一些基礎服務,比如繪圖,計算位置等,腳本就可以非常簡單控制游戲。甚至快速構建新游戲。你應該知道QUAKE引擎吧?
這里提供給你一個計算器的小程序,應用了EBNF理論,支持表達式,比如(2+3*6)*4+4,你自己體驗一下它的簡潔和強大。
/*
simple integer arithmetic calculator according to the EBNF
<exp> -> <term>{<addop><term>}
<addop>->+|-
<term>-><factor>{<mulop><factor>}
<mulop> -> *
<factor> -> ( <exp> )| Number
Input a line of text from stdin
Outputs "Error" or the result.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

char token;/*global token variable*/
/*function prototypes for recursive calls*/
int exp(void);
int term(void);
int factor(void);

void error(void)
{
fprintf(stderr,"Error\n");
exit(1);
}

void match(char expectedToken)
{
if(token==expectedToken)token=getchar();
else error();
}

main()
{
int result;
token = getchar();/*load token with first character for lookahead*/
result = exp();
if(token=='\n')/*check for end of line */
printf("Result = %d\n",result);
else error();/*extraneous cahrs on line*/
return 0;
}

int exp(void)
{
int temp = term();
while((token=='+')||(token=='-'))
switch(token)
{
case '+':
match('+');
temp+=term();
break;
case '-':
match('-');
temp-=term();
break;
}
return temp;
}

int term(void)
{
int temp = factor();
while (token=='*')
{
match('*');
temp*=factor();
}
return temp;
}

int factor(void)
{
int temp;
if(token=='('){
match('(');
temp = exp();
match(')');
}
else if(isdigit(token)){
ungetc(token,stdin);
scanf("%d",&temp);
token = getchar();
}
else error();
return temp;
}
其實編程學到一定程度總是沒有方向了,總是在問學C/C++下一步怎麼學啊,覺得掌握了該語言了雲雲,實際上,你缺少的就是這些軟的東西,缺少的是理論。
編譯原理不是單一的理論,它涵蓋了一個niche,裡面可以學到很多其他知識,比如正則表達式、BNF、EBNF、分析樹、語法樹還有很多運行時環境等知識
這些給你帶來的是非常豐厚的回報。不說多了,學完運行時,你就會加深對C++語言本身的理解。
你要想有好的發展,還是學吧。

8. 有關編譯原理

編譯原理的"原理"其實跟C語言關系不太大,除非你是想親手實踐一個小型的編譯器,對於數據結構,你明白基本的隊列和棧基本就夠了,如果還沒全懂,不必怕看不懂編譯原理.
編譯原理比較難學,但是在學的過程中我覺得一定要明白每一種詞法分析到底是在干什麼,不要只為了編譯原理的題而學,那樣我覺得學起來會非常抽象.
至於書,我覺得還是使用清華大學的<編譯原理>,張素琴,呂映芝那本.這本書也是編譯原理的經典教材,雖然不是特別好懂,但我覺得這本書你"熟讀千遍",肯定會有所收獲.把前七章學完,"原理"部分就完畢了.
最好這門課找些視頻教程學來會容易一些,否則真是要自己硬看的話還是有一定難度的...

9. 學完編譯原理這門課,用c語言或者c++語言,編一個預測分析的程序,對預測分析也至少測試三個句子(含錯誤

我寫好的.
scan.h

/*
* scan.h
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/

#ifndef _SCAN_H_
#define _SCAN_H_

#include <string>
#include <fstream>
using namespace std;

typedef enum
{
ENDFILE,ERROR,
ELSE,IF,INT,RETURN,VOID,WHILE,
ID,NUM,
ASSIGN,EQ,LT,GT,LE,GE,NE,ADD,SUB,MUL,DIV,SEMI,LPAREN,RPAREN,LZK,RZK,LDK,RDK,COMMA
}
TokenType;

class Scan
{
private:
string tokenStr;
string linebuffer;
ifstream * in;
int linepos;
int lineno;
bool EOF_Flag;
bool traceScan;
void printToken(TokenType tt,const string &tok);
public:
Scan(ifstream * in)
{
this->in=in;
linepos=0;
linebuffer="";
lineno=0;
EOF_Flag=false
traceScan=true;
}
char getNextChar();

void ungetNextChar();

TokenType reservedLookup(string &s);

void setTraceScan(bool f);

bool getTraceScan();

TokenType getToken();

string getTokenStr();

};
#endif

scan.cpp

/*
* scan.cpp
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/

#include <string>
#include <fstream>
#include <iostream>
using namespace std;

#include "scan.h"

typedef enum

StateType;

static struct
{
string str;
TokenType tok;
} reservedWords[6]
=,,,,,};

char Scan::getNextChar()
{
if(linepos>=linebuffer.size())
{
if(getline(*in,linebuffer))
{
linebuffer+="\n";
lineno++;
linepos=0;
return linebuffer[linepos++];
}
else
{
EOF_Flag=true;
return EOF;
}
}
else
return linebuffer[linepos++];
}

void Scan::ungetNextChar()
{
if(!EOF_Flag) linepos--;
}

TokenType Scan::reservedLookup(string &s)
{
for(int i=0;i<6;i++)
if(s==reservedWords[i].str)
return reservedWords[i].tok;
return ID;
}

void Scan::setTraceScan(bool f)
{
traceScan=f;
}

bool Scan::getTraceScan()
{
return traceScan;
}

TokenType Scan::getToken()
{
tokenStr="";
TokenType currentToken;
StateType state=START;

while(state!=DONE)
{
bool save=false;
char c=getNextChar();
switch (state) {
case START:
if(c>='0'&&c<='9'){
state=INNUM;
save=true;
}
else if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){
state=INID;
save=true;
}
else if(c==' '||c=='\t'||c=='\n')
{
state=START;
}
else if(c=='/'){
state=SLASH;
}
else if(c=='='){
state=TEMPE;
}
else if(c=='>')
state=TEMPG;
else if(c=='<')
state=TEMPL;
else if(c=='!')
state=INNOTEQ;
else
{
state=DONE;
switch (c) {
case EOF:
currentToken=ENDFILE;
break;
case '+':
currentToken=ADD;
break;
case '-':
currentToken=SUB;
break;
case '*':
currentToken=MUL;
break;
case '(':
currentToken=LPAREN;
break;
case ')':
currentToken=RPAREN;
break;
case '[':
currentToken=LZK;
break;
case ']':
currentToken=RZK;
break;
case '{':
currentToken=LDK;
break;
case '}':
currentToken=RDK;
break;
case ';':
currentToken=SEMI;
break;
case ',':
currentToken=COMMA;
break;
default:
currentToken=ERROR;
break;
}
}
break;
case INNUM:
if(c<'0'||c>'9')
{
ungetNextChar();
state=DONE;
currentToken=NUM;
}
else
save=true;
break;
case INID:
if(!((c>='a'&&c<='z')||(c>='A'&&c<='Z')))
{
ungetNextChar();
state=DONE;
currentToken=ID;
}
else
save=true;
break;
case SLASH:
if (c!='*')
{
state=DONE;
currentToken=DIV;
}
else
state=INCOMMENT1;
break;
case INCOMMENT1:
if (c!='*')
state=INCOMMENT1;
else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}
else
state=INCOMMENT2;
break;
case INCOMMENT2:
if (c=='*') {
state=INCOMMENT2;
}else if(c=='/'){
state=START;
}else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}else {
state=INCOMMENT1;
}
break;
case TEMPE:
if (c=='=') {
state=DONE;
currentToken=EQ;
}else{
state=DONE;
ungetNextChar();
currentToken=ASSIGN;
}
break;
case TEMPG:
if (c=='=') {
state=DONE;
currentToken=GE;
}else{
state=DONE;
ungetNextChar();
currentToken=GT;
}
break;
case TEMPL:
if (c=='=') {
state=DONE;
currentToken=LE;
}else{
state=DONE;
ungetNextChar();
currentToken=LT;
}
break;
case INNOTEQ:
if (c=='=') {
state=DONE;
currentToken=NE;
}else {
state=DONE;
ungetNextChar();
currentToken=ERROR;
}
break;

default:
cerr<<"Scanner Bug: state= "<<state<<endl;
state=DONE;
currentToken=ERROR;
break;
}
if(save){
string newChar(1,c);
tokenStr+=newChar;
}
if (state==DONE&¤tToken==ID)
currentToken=reservedLookup(tokenStr);
}
if (traceScan) {
cout<<"Scan at line "<<lineno<<" token: ";
printToken(currentToken, tokenStr);
cout<<endl;
}
return currentToken;
}

string Scan::getTokenStr()
{
return tokenStr;
}

void Scan::printToken(TokenType tt,const string &tok)
{
string type;
switch (tt) {
case ENDFILE:
type="EOF";
break;
case ERROR:
type="ERROR";
break;
case ELSE:
case IF:
case INT:
case RETURN:
case VOID:
case WHILE:
type="reserved word";
break;
case ID:
type="ID";
break;
case NUM:
type="NUM";
break;
case ASSIGN:
type="=";
break;
case EQ:
type="==";
break;
case LT:
type="<";
break;
case GT:
type=">";
break;
case LE:
type="<=";
break;
case GE:
type=">=";
break;
case NE:
type="!=";
break;
case ADD:
type="+";
break;
case SUB:
type="-";
break;
case MUL:
type="*";
break;
case DIV:
type="/";
break;
case SEMI:
type=";";
break;
case LPAREN:
type="(";
break;
case RPAREN:
type=")";
break;
case LZK:
type="[";
break;
case RZK:
type="]";
break;
case LDK:
type="{";
case RDK:
type="}";
break;
case COMMA:
type=",";
break;
default:
break;
}
cout << type<<": "<<tok;
}

main.cpp

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "scan.h"

int main (int argc, char * const argv[]) {
string fileName="/Users/huanglongyin/scan_in.txt";
//cout<< "File name: ";
//cin>>fileName;
ifstream in(fileName.c_str());
if(!in){
cerr<<"Error occurs when openning file "<<fileName<<endl;
return -1;
}
Scan scan(&in);
while(scan.getToken()!=ENDFILE);
return 0;
}

熱點內容
linux怎麼將驅動編譯進內核 發布:2024-05-19 10:23:47 瀏覽:767
c語言讀程序題 發布:2024-05-19 10:13:52 瀏覽:674
新的安卓手機怎麼樣下載微信 發布:2024-05-19 10:05:06 瀏覽:878
加9的演算法 發布:2024-05-19 10:04:15 瀏覽:263
新名圖配置怎麼樣 發布:2024-05-19 09:31:30 瀏覽:94
php獲取子節點 發布:2024-05-19 09:21:18 瀏覽:160
php生成html 發布:2024-05-19 09:20:24 瀏覽:795
keil編譯步驟 發布:2024-05-19 08:58:12 瀏覽:702
ipad有哪些好用的c語言編譯器 發布:2024-05-19 08:41:56 瀏覽:767
征途手游版腳本 發布:2024-05-19 08:38:11 瀏覽:165