CC(Compiler Compiler)
CC的意思就是“編譯器的編譯器”。
你可以定義一種上下文無關文法(CFG),然后針對這個特定的CFG你可以寫出一個C程序來解釋這種CFG,那么你編的這個C程序就叫做“編譯器”。只不過你的編譯器只能編譯特定的CFG。而實際上,G++只能編譯C++、JAVAC只能編譯Java,這些都是編譯器。
而對於任意給定的CFG,我可以寫出一段C程序(這就是Compiler's Compiler)來printf出一段C程序(Compiler),printf出來的這段C程序就是給定CFG的編譯器。那么,我寫的那段C程序就叫做CC(生成編譯器的編譯器)。
CC實際上是一種問題,可以定義CFG的CC、也可以定義RG(正則語法)的CC。
正則語法的CC顯然就是我們常用的工具--------正則表達式。
上下文無關文法的CC有前人的工具:YACC(C++)、JavaCC
一提到CC,必然考慮兩點:
- 源語言,比如源語言可以是正則語言、上下文無關語言
- 目標語言,比如Java、C++
CC還有另外一種說法:Parser Generator(解釋器的生成器)
怎么操作的?
寫一個文件,這個文件內容由“文法”+“處理代碼”兩種代碼混合組成。
一言以蔽之(in a nutshell),這些編譯工具讓人們免除解析文法的過程,而讓人專注於文法解析完成之后的邏輯處理。
YACC(Yet Another Compiler Compiler)
YACC是一個經典的生成語法分析器的工具。yacc生成的編譯器主要是用C語言寫成的語法解析器(Parser),需要與詞法解析器Lex一起使用,再把兩部份產生出來的C程序一並編譯。
yacc的輸入是巴科斯范式(BNF)表達的語法規則以及語法規約的處理代碼,Yacc輸出的是基於表驅動的編譯器,包含輸入的語法規約的處理代碼部分。
yacc是開發編譯器的一個有用的工具,采用LALR(1)語法分析方法。
Yacc最初由AT&T的Steven C. Johnson為Unix操作系統開發,后來一些兼容的程序如Berkeley Yacc,GNU bison,MKS yacc和Abraxas yacc陸續出現。它們都在原先基礎上做了少許改進或者增加,但是基本概念是相同的。
由於所產生的解析器需要詞法分析器配合,因此Yacc經常和詞法分析器的產生器——一般就是Lex——聯合使用。IEEE POSIX P1003.2 標准定義了Lex和Yacc的功能和需求。
bison和flex
bison是yacc的進化版,flex是lex的進化版
JavaCC
JavaCC(Java Compiler Compiler)是一個用JAVA開發的受歡迎的語法分析生成器。這個分析生成器工具可以讀取上下文無關且有着特殊意義的語法並把它轉換成可以識別且匹配該語法的JAVA程序。JavaCC可以在Java虛擬機(JVM) V1.2或更高的版本上使用,它是100%的純Java代碼,可以在多種平台上運行,與Sun當時推出Java的口號"Write Once Run Anywhere"相一致。JavaCC還提供JJTree工具來幫助我們建立語法樹,JJDoc工具為我們的源文件生成BNF范式(巴科斯-諾爾范式)文檔(Html)
與YACC和Bison最大的不同在於,JavaCC基於自上而下算法對CFG進行解析。
JavaCC是如此的有用,以至於很多有名的庫底層都用它來實現語法解析器。這些庫包括:
- Apache Derby
- BeanShell
- FreeMarker
- PMD
- Vaadin
- Apache Lucene
- JavaParser
參考資料
https://en.wikipedia.org/wiki/JavaCC
https://en.wikipedia.org/wiki/Bison