內容簡介
Terence Parr: The Definitive ANTLR 4 Reference (ISBN 9781934356999).Copyright ?2012 The Pragmatic Programmers, LLC.Simplified Chinese translation copyright ?2017 by China Machine Press.No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or any information storage and retrieval system, without permission, in writing, from the publisher.All rights reserved.本書中文簡體字版由The Pragmatic Programmers, LLC授權機械工業齣版社在全球齣版發行。未經齣版者書麵許可,不得以任何方式抄襲、復製或節錄本書中的任何部分。
目錄
譯者序
前言
緻謝
第一部分 ANTLR和計算機語言簡介
第1章初識ANTLR 3
1.1安裝ANTLR 3
1.2運行ANTLR並測試識彆程序 5
第2章縱觀全局 9
2.1從ANTLR元語言開始 9
2.2實現一個語法分析器 11
2.3你再也不能往核反應堆多加水瞭 13
2.4使用語法分析樹來構建語言類應用程序 15
2.5語法分析樹監聽器和訪問器 17
第3章入門的ANTLR項目 20
3.1ANTLR工具、運行庫以及自動生成的代碼 21
3.2測試生成的語法分析器 23
3.3將生成的語法分析器與Java程序集成 25
3.4構建一個語言類應用程序 26
第4章快速指南 29
4.1匹配算術錶達式的語言 30
4.2利用訪問器構建一個計算器 35
4.3利用監聽器構建一個翻譯程序 38
4.4定製語法分析過程 41
4.5神奇的詞法分析特性 45
第二部分 使用ANTLR語法開發語言類應用程序
第5章設計語法 53
5.1從編程語言的範例代碼中提取語法 54
5.2以現有的語法規範為指南 56
5.3使用ANTLR語法識彆常見的語言模式 56
5.4處理優先級、左遞歸和結閤性 62
5.5識彆常見的詞法結構 66
5.6劃定詞法分析器和語法分析器的界綫 71
第6章探索真實的語法世界 74
6.1解析CSV文件 75
6.2解析JSON 77
6.3解析DOT語言 83
6.4解析Cymbol語言 88
6.5解析R語言 91
第7章將語法和程序的邏輯代碼解耦 98
7.1從內嵌動作到監聽器的演進 99
7.2使用語法分析樹監聽器編寫程序 100
7.3使用訪問器編寫程序 103
7.4標記備選分支以獲取精確的事件方法 105
7.5在事件方法中共享信息 107
第8章構建真實的語言類應用程序 114
8.1加載CSV數據 114
8.2將JSON翻譯成XML 117
8.3生成調用圖 121
8.4驗證程序中符號的使用 124
第三部分 高級特性
第9章錯誤報告與恢復 133
9.1錯誤處理入門 133
9.2修改和轉發ANTLR的錯誤消息 137
9.3自動錯誤恢復機製 141
9.4勘誤備選分支 152
9.5修改ANTLR的錯誤處理策略 152
第10章屬性和動作 156
10.1使用帶動作的語法編寫一個計算器 157
10.2訪問詞法符號和規則的屬性 162
10.3識彆關鍵字不固定的語言 165
第11章使用語義判定修改語法分析過程 168
11.1識彆編程語言的多種方言 169
11.2關閉詞法符號 172
11.3識彆歧義性文本 174
第12章掌握詞法分析的“黑魔法” 180
12.1將詞法符號送入不同通道 181
12.2上下文相關的詞法問題 184
12.3字符流中的孤島 194
12.4對XML進行語法分析和詞法分析 198
第四部分 ANTLR參考文檔
第13章探究運行時API 209
13.1包結構概覽 209
13.2識彆器 210
13.3輸入字符流和詞法符號流 212
13.4詞法符號和詞法符號工廠 213
13.5語法分析樹 215
13.6錯誤監聽器和監聽策略 216
13.7提高語法分析器的速度 217
13.8無緩衝的字符流和詞法符號流 217
13.9修改ANTLR的代碼生成機製 219
第14章移除直接左遞歸 221
14.1直接左遞歸備選分支模式 222
14.2左遞歸規則轉換 223
第15章語法參考 226
15.1語法詞匯錶 226
15.2語法結構 229
15.3文法規則 232
15.4動作和屬性 241
15.5詞法規則 246
15.6通配符與非貪婪子規則 250
15.7語義判定 253
15.8選項 257
15.9ANTLR命令行參數 259
參考文獻 263
前言/序言
Preface前 言ANTLR是一款強大的語法分析器生成工具,可用於讀取、處理、執行和翻譯結構化的文本或二進製文件。它被廣泛應用於學術領域和工業生産實踐,是眾多語言、工具和框架的基石。Twitter搜索使用ANTLR進行語法分析,每天處理超過20億次查詢;Hadoop生態係統中的Hive、Pig、數據倉庫和分析係統所使用的語言都用到瞭ANTLR;Lex Machina將ANTLR用於分析法律文本;Oracle公司在SQL開發者IDE和遷移工具中使用瞭ANTLR;NetBeans公司的IDE使用ANTLR來解析C++;Hibernate對象-關係映射框架(ORM)使用ANTLR來處理HQL語言。
除瞭這些鼎鼎大名的項目之外,還可以利用ANTLR構建各種各樣的實用工具,如配置文件讀取器、遺留代碼轉換器、維基文本渲染器,以及JSON解析器。我編寫瞭一些工具,用於創建數據庫的對象-關係映射、描述三維可視化以及在Java源代碼中插入性能監控代碼。我甚至為一次演講編寫瞭一個簡單的DNA模式匹配程序。
一門語言的正式描述稱為語法(grammar),ANTLR能夠為該語言生成一個語法分析器,並自動建立語法分析樹——一種描述語法與輸入文本匹配關係的數據結構。ANTLR也能夠自動生成樹的遍曆器,這樣你就可以訪問樹中的節點,執行自定義的業務邏輯代碼。
本書既是ANTLR 4的參考手冊,也是解決語言識彆問題的指南。你會學到如下知識:
識彆語言樣例和參考手冊中的語法模式,從而編寫自定義的語法。
循序漸進地為從簡單的JSON到復雜的R語言編寫語法。同時還能學會解決XML和Python中棘手的識彆問題。
基於語法,通過遍曆自動生成的語法分析樹,實現自己的語言類應用程序。
在特定的應用領域中,自定義識彆過程的錯誤處理機製和錯誤報告機製。
通過在語法中嵌入Java動作(action),對語法分析過程進行完全的掌控。
本書並非教科書,所有的討論都是基於實例的,旨在令你鞏固所學的知識,並提供語言類應用程序的基本範例。
本書的讀者對象本書尤其適用於對數據讀取器、語言解釋器和翻譯器感興趣的開發者。雖然本書主要利用ANTLR來完成這些工作,你仍然可以學到很多有關詞法分析器和語法分析器的知識。初學者和專傢都需要本書來高效地使用ANTLR 4。如果希望學習第三部分中的高級特性,你需要先瞭解之前章節中的ANTLR基礎知識。此外,讀者還需要具備一定的Java功底。
Honey Badger版本ANTLR 4的版本代號是“Honey Badger”,這個名字來源於一段著名的YouTube短片The Crazy Nastyass Honey Badger(網址為:http://www.youtube.com/watch?v=4r7wHMg5Yjg)中的勇敢無畏的主角——一隻蜜獾。它敢吃你給它的任何東西,根本不在乎那是什麼!
ANTLR 4有哪些神奇之處ANTLR 4引入瞭一些新功能,降低瞭入門門檻,使得語法和語言類應用程序的開發更加容易。最重要的新特性在於,ANTLR 4幾乎能夠處理任何語法(除瞭間接左遞歸,稍後會提到)。在ANTLR將你的語法轉換成可執行的、人類可讀的語法分析代碼的過程中,語法衝突或者歧義性警告不會再齣現。
無論多復雜的語法,隻要你提供給ANTLR自動生成的語法分析器的輸入是閤法的,該語法分析器就能夠自動識彆之。當然,你需要自行保證該語法能夠準確地描述目標語言。
ANTLR語法分析器使用瞭一種名為自適應LL(*)或者ALL(*)(讀作“all star”)的新技術,它是由我和Sam Harwell一起開發的。ALL(*)是ANTLR 3中的LL(*)的擴展,在實際生成的語法分析器執行前,它能夠在運行時以動態方式對語法執行分析,而非先前的靜態方式。由於ALL(*)語法分析器能夠訪問實際的輸入文本,通過反復分析語法的方式,它最終能夠決定如何識彆輸入文本。相比之下,靜態分析必須考慮所有可行的(無限長的)輸入序列。
在實踐中,擁有ALL(*)意味著你無須像在其他語法分析器生成工具(包括ANTLR 3)中那樣,扭麯語法以適應底層的語法分析策略。如果你曾經為ANTLR 3的歧義性警告和yacc的歸約/歸約衝突(reduce/reduce conflict)而抓狂,ANTLR 4就是你的不二之選!
另外一個強大的新功能是ANTLR 4極大地簡化瞭匹配某些句法結構(如編程語言中的算術錶達式)所需的語法規則。長久以來,處理錶達式都是ANTLR語法(以及手工編寫的遞歸下降語法分析器)的難題。識彆錶達式最自然的語法對於傳統的自頂嚮下的語法分析器生成器(如ANTLR 3)是無效的。現在,利用ANTLR 4,你可以通過如下規則匹配錶達式:
類似expr的自引用規則是遞歸的,更準確地說,是左遞歸(left recursive)的,因為它的至少一個備選分支直接引用瞭它自己。
ANTLR 4自動將類似expr的左遞歸規則重寫成瞭等價的非左遞歸形式。唯一的約束是左遞歸必須是直接的,也就是說規則直接引用自身。一條規則不能引用另外一條規則,如果後者的備選分支之一在左側直接引用瞭前者(而沒有匹配一個詞法符號)。詳見5.4節。
除瞭上述兩項與語法相關的改進,ANTLR 4還使得編寫語言類應用程序更加容易。ANTLR生成的語法分析器能夠自動建立名為語法分析樹(parse tree)的視圖,其他程序可以遍曆此樹,並在所需處理的結構處觸發迴調函數。在先前的ANTLR 3中,用戶需要補充語法來創建樹。除瞭自動建立樹結構之外,ANTLR 4還能自動生成語法分析樹遍曆器的實現:監聽器(listener)或者訪問器(visitor)。監聽器與在XML文檔的解析過程中響應SAX事件的處理器相似。
由於擁有以下幾點ANTLR 3所不具備的新特性,ANTLR 4顯得非常容易上手:
最大的改變是ANTLR 4降低瞭語法中內嵌動作(代碼)的重要性,取而代之的是監聽器和訪問器。新機製將語法和應用的邏輯代碼解耦,使得應用程序本身被封裝起來,而非散落在語法的各處。在沒有內嵌動作的情況下,你可以在多個程序中復用同一份語法,甚至都無須重新編譯生成的語法分析器。雖然ANTLR仍然允許內嵌動作的存在,但是在ANTLR 4中,它們更像是一種進階用法。這樣的行為能夠最大程度地掌控語法分析過程,但其代價是語法復用性的喪失。
由於ANTLR能夠自動生成語法分析樹和樹的遍曆器,在ANTLR 4中,你無須再編寫樹語法。取而代之的是一些廣為人知的設計模式,如訪問者模式。這意味著,在學會瞭ANTLR語法之後,你就可以重迴自己熟悉的Java領域來實現真正的語言類應用程序。
ANTLR 3的LL(*)語法分析策略不如ANTLR 4的ALL(*)強大,所以ANTLR 3為瞭能夠正確識彆輸入的文本,有時候不得不進行迴溯。迴溯的存在使得語法的調試格外睏難,因為生成的語法分析器會對同樣的輸入進行(遞歸的)多趟語法分析。迴溯也為語法分析器在麵對非法輸入時給齣錯誤消息設置瞭重重障礙。
ANTLR 4是25年前我讀研究生時所走的一小段彎路的成果。我想,我也許會稍微改變我曾經的座右銘。
為什麼不花5天時間編程,來使你25年的生活自動化呢?ANTLR 4正是我所期望的語法分析器生成器,現在,我終於能夠迴頭去研究我原先在20世紀80年代試圖解決的問題——假如我還記得它的話。
本書的主要內容本書是你所能找到的有關ANTLR 4的信息源中最好、最完整的。免費的在綫文檔提供瞭足夠多有關基礎語法的句法和語義的資料,不過沒有詳細解釋ANTLR的相關概念。在本書中,識彆語言的語法模式和將其錶述為ANTLR語法的內容是獨一無二的。貫穿全書的示例能夠在構建語言類應用程序方麵助你一臂之力。本書可幫助你融會貫通,成為ANTLR專傢。
本書由四部分組成。
第一部分介紹瞭ANTLR,提供瞭一些與語言相關的背景知識,並展示瞭ANTLR的一些簡單應用。在這一部分中,你會瞭解ANTLR的句法以及主要用途。
第二部分是一部有關設計語法和使用語法來構建語言類應用程序的“百科全書”。
第三部分展示瞭自定義ANTLR生成的語法分析器的錯誤處理機製的方法。隨後,你會學到在語法中嵌入動作的方法——在某些場景下,這樣做比建立樹並遍曆之更簡單,也更有效率。此外,你還將學會使用語義判定(semantic predicate)來修改語法分析器的行為,以便解決一些充滿挑戰的識彆難題。
本部分的最後一章解決瞭一些充滿挑戰的識彆難題,例如識彆XML和Python中的上下文相關的換行符。
第四部分是參考章節,詳細列齣瞭ANTLR語法元語言的所有規則和ANTLR運行庫的用法。
完全不瞭解語法和語言識彆工具的讀者請務必從頭開始閱讀。具備ANTLR 3使用經驗的用戶可從第4章開始閱讀以學習ANTLR 4的新功能。
有關ANTLR的更多在綫學習資料在http://www.antlr.org上,你可以找到ANTLR、ANTLRWorks2圖形界麵開發環境、文檔、預製的語法、示例、文章,以及文件共享區。技術支持郵件組是一個對初學者十分友好的公開討論組。
Terence Parr2012年11月於舊金山大學緻 謝Acknowledgements大約25年前,我開始緻力於ANTLR的相關工作。那時,在許多人的幫助下,ANTLR工具的句法和功能逐漸成形,在此,我嚮他們緻以由衷的感謝。要特彆感謝的是Sam Harwell,他是ANTLR 4的另一位開發者。他不僅幫助我完成瞭此軟件,而且在ALL(*)語法分析算法上做齣瞭突齣的貢獻。Sam也是ANTLRWorks2語法IDE的開發者。
感謝以下人員對本書進行瞭技術審閱:Oliver Ziegermann、Sam Rose、Kyle Ferrio、Maik Schmidt、Colin Yates、Ian Dees、Tim Ottinger、Kevin Gisi、Charley Stran、Jerry Kuch、Aaron Kalair、Michael Bevilacqua-Linn、Javier Collado、Stephen Wolff以及Bernard Kaiflin。同時,我還要感謝那些在本書和ANTLR 4軟件處於beta版本時報告問題的熱心讀者。尤其要感謝的是Kim Shrier和Graham Wideman,他們二位的審閱格外認真。Graham的審閱報告之仔細、翔實和廣博,令我不知是該緊握他的手予以感謝,還是該為自己的疏漏羞愧難當。
最後,我還要感謝編輯Susannah Davidson Pfalzer,她一如既往地支持我完成瞭三本書的創作。她提齣的寶貴建議和對本書內容的精雕細琢使本書更加完美。
The Translator's Words譯 者 序四年前,我在讀研究生時曾經參考龍書編寫過一個簡單的編譯器前端。經過一個星期的實踐後,我意識到,從頭實現一個編譯器前端的難度遠遠超齣瞭一般開發者的能力。編寫編譯器前端所需要的理論基礎、技術功底和精力都遠非普通軟件可比。
幸運的是,ANTLR的齣現使這個過程變得易如反掌。ANTLR能夠根據用戶定義的語法文件自動生成詞法分析器和語法分析器,並將輸入文本處理為(可視化的)語法分析樹。這一切都是自動進行的,所需的僅僅是一份描述該語言的語法文件。
一年前,我在為淘寶的一個內部數據分析係統設計DSL時,第一次接觸到瞭ANTLR。使用ANTLR之後,我在一天之內就完成瞭整個編譯器前端的開發工作,從而能夠迅速開始處理真正的業務邏輯。從那時起,我就被它強大的功能所深深吸引。簡而言之,ANTLR能夠解決彆的工具無法解決的問題。
軟件改變瞭世界。數十年來,信息化的浪潮在全球顛覆著一個又一個的行業。然而,整個世界的信息化程度還遠未達到閤理的高度,還有大量傳統行業的生産力可以被信息化所解放。在這種看似矛盾的情形背後存在著一條鴻溝:大量從事傳統行業的人員擁有在本行業中無與倫比的業務知識和經驗,卻苦於跟不上現代軟件發展的腳步。解決這個問題的根本方法就是DSL(Domain Specific Language),讓傳統行業的人員能夠用嚴謹的方式與計算機對話。其實,本質上任何編程語言都是一種DSL,殊途同歸。
而實現DSL的主要睏難就在編譯器前端。編譯器被稱為軟件工程皇冠上的明珠。一直以來,對於普通的開發者而言,編譯器的設計與實現都如同詩中描述的那樣:“白雲在青天,可望不可即。”
ANTLR改變瞭這一切。ANTLR自動生成的編譯器前端高效、準確,能夠將開發者從繁雜的編譯理論中解放齣來,集中精力處理自己的業務邏輯。ANTLR 4引入的自動語法分析樹創建與遍曆機製,極大地提高瞭語言識彆程序的開發效率。
時至今日,ANTLR仍然是Java世界中實現編譯器的不二之選,同時,它對其他編程語言也提供瞭不同程度的支持。在開始學習ANTLR時,我發現國內有關ANTLR的資料較為貧乏,這催生瞭我翻譯本書的念頭。我期望通過本書的翻譯,讓更多的開發者能夠更加自如地解決職業生涯中碰到的難題。
本書沒有冗長的理論,而是從一些具體的需求齣發,由淺入深地介紹瞭語言的背景知識、ANTLR語法的設計方法以及基於ANTLR 4實現語言識彆程序的詳細步驟。它尤其適用於對語言識彆程序的開發感興趣的開發者。不過,假如你現在沒有這樣的需求,我仍然建議你閱讀本書,因為它能夠開拓你的眼界,讓你深入實現層麵加深對編程語言的理解。
感謝原作者Terence Parr教授嚮這個世界貢獻瞭如此優秀的軟件。您編寫的ANTLR極大地提高瞭開發效率,這實際上等於延長瞭廣大開發者的生命。
感謝孫嵐和石寒舟兩位前輩對本書審校付齣的心血,您二位的寶貴建議令我受益匪淺。
感謝華章公司的和靜編輯對本書的翻譯提供的支持與幫助。
感謝我的妻子張潔珊女士,你的理解和陪伴保障瞭翻譯過程如期完成。
感謝每一位讀者,你的潛心研習與融會貫通將會令本書更有價值。
截止本書譯完的2016年12月,ANTLR已經演進到瞭4.6。在這個過程中,一些Breaking Change齣現瞭,本書中的部分示例代碼已經不再有效。因此,我盡自己所能,結閤勘誤錶,使用最新版的ANTLR對它們進行瞭逐個驗證。對於失效的代碼,我通過譯注的方式予以修正。由於譯者水平有限,書中齣現錯誤與不妥之處在所難免,懇請讀者批評指正。
張 博2017年1月
ANTLR 4權威指南 下載 mobi epub pdf txt 電子書 格式