1. 程式人生 > >自制指令碼語言(3) LR(1) parser generator的實現

自制指令碼語言(3) LR(1) parser generator的實現

摘要:實現了LR(1)的parser generator,讀取記錄grammar的txt檔案,輸出記錄action table與goto table的txt檔案。

原始碼在http://download.csdn.net/detail/nklofy/8878579

按照之前的設計並稍微修改,程式的主體流程是:

首先讀取grammar.txt。用Map<String, Symbol> gen_symbols儲存全部的符號,終結符放入Set<Symbol> gen_NTs,非終結符放入Set<Symbol> gen_tokens。用List<Grammar> gen_grammars儲存各條語法生成式。呼叫函式是input( ), inputGrammars( ), buildGrammars( )。這裡另外還呼叫了一個函式generateGrammarTable( ),生成了List<GrammarTable> gen_gr_tables,這是為了將所有grammar編號,在action table中規約動作需要一個語法控制代碼編號。則parser時可以根據歸約控制代碼選擇合適的函式生成AST。

其次是生成所有符號的first集。呼叫函式getFirst( ),將所有非終結符的First集計算出來。這裡用了一個小技巧,語法的逆序遍歷。因為語法越下降,越接近終結符,所以逆序遍歷可以便於First集從終結符向非終結符傳播,節省迴圈的次數,提高時間效率。

然後是分析gen_grammars,生成全部的規範族和項集。這一功能是由getCCs( )函式從CC0開始展開而實現的。它呼叫getCloure( )函式獲得各個CC中的全部items,同時依靠getGoto( )函式將item的佔位符向前移動一位而生成新的CC(若該CC已存在,則不生成),同時得到舊CC的goto_table。再繼續呼叫getClosure( )得到新的CC中的全部items。反覆執行直到沒有新的CC生成。

最後分析gen_CCs生成action table和goto table。遍歷gen_CCs中所有CC物件,按照其goto_table儲存的symbol和轉移CC序號,當symbol為token時,編輯action table,若該CC屬於控制代碼則得到rXX,否則為sXX,分別代表reduce和shift動作;當symbol為非終結符時,編輯goto table,填入gXX以表示symbol歸結後跳轉的新狀態。action table完成後,寫入out.txt檔案。

設計的類及其屬性、方法如下:

public class ParserGenerator {
	private List<ActionTable> gen_action_tables
	private List<GrammarTable> gen_gr_tables
	private List<CC> gen_CCs=new ArrayList<CC>();
	private List<Grammar> gen_grammars=new ArrayList<Grammar>();
	private Map<String,Symbol> gen_symbols
	private Set<Symbol> gen_tokens
	private Set<Symbol> gen_NTs
	private Map<Symbol,ArrayList<Kernel>> gen_kernels
	static public void main(String[] args)
	private boolean input(String filename)
	private boolean inputGrammars(Scanner in)
	private Grammar buildGrammar(List<String> list)
	private void output(String filename)
	private boolean getFirst()	
	private boolean getClosure(CC cc)
	private CC getGoto(Item item)	
	private boolean getCCs()
	private void generateGrammarTable()
	private void generateActionTable()
	private void createActionTable(ActionTable table,CC cc,Symbol token)
	private void createGotoTable(ActionTable table,CC cc,Symbol sym)	
}
class Symbol{	
	Set<Symbol> First
	List<Production> head_grammar
	Boolean isFinal
	String name
}
class Grammar{
	Symbol head
	List<Production> productions
}
class Production{
	List<Symbol> symbols
	int index_gr_tb
}

class Item{
	Symbol head
	List<Symbol> symbols
	int position
	Symbol look_ahead
	int index_gr_tb	
	boolean eqItem(Item item)
	boolean inItemList(List<Item> items)
}
class CC{
	Item kernel_item;
	List<Item> items
	Map<Symbol,CC> goto_tb
	boolean got_Closure
	boolean got_Goto
	boolean in_table
	boolean is_reduce
	int index_cc
	int index_gr
}
class ActionTable{
	Map<String, String> action_t
	Map<String, String> goto_t
}
class GrammarTable{
	String head
	ArrayList<String> symbols
}
class Kernel{
	CC cc_in
	Item item_in
	boolean hasItem(Item item)
	}	
}

原始碼在http://download.csdn.net/detail/nklofy/8878579, 或 https://github.com/nklofy/Compiler