LL(1)分析器的Java实现
来源:互联网 发布:优化设计吧 编辑:程序博客网 时间:2024/06/07 02:18
1. 基本思路
1. 从外部文件读入文法规则;
2. 分析是否存在左递归,如果存在则消除之;
3. 求取每个候选式的FIRST集;
4. 求各非终结符的FOLLOW集;
5. 根据LL(1)文法的3个判定条件判断其是否是LL(1)文法;
6. 如果是LL(1)文法就构造分析表,并判断输入的句子是否是该文法的句子。
2. 类设计
依照基本思路,每一项都用一个类来实现,再都多一个共用的存储文法规则的类。一共7个类,主要功能如下:
2.1 LL1类
入口类,一个main函数和一个无实参构造函数。构造函数实现读入文法规则的功能,并将每一行文法规则送Language类存储,最后调用LL1Help类对象,将控制权转给LL1Help类对象。
2.1.1 属性
private BufferedReader buffer;private Language language;private LL1Help ll1Help;
2.1.2 方法
public LL1()public static void main(String[] args)
2.2 LL1Help类
辅助类,通过displayMessage方法控制程序的输入和输出。
2.2.1 属性
private Language language;private LeftRecursive leftRecursive;private FirstCollection firstCollection;private FollowCollectionfollowCollection;private AnalysisTable analysisTable;
2.2.2 方法
public LL1Help(Languagelanguage)public void displayMessage() //控制程序的输入和输出public boolean isLL_1() //判断输入的文法是否是LL(1)文法privateSet<String> getMixed(List<Set<String>> sets) // 得到多个集合的交集,用于判断LL(1)文法private StringdisplaySet(Set<String> elementSet) // 辅助集合的输出,如{a, b, c, d}
2.3 Language类
存储文法规则。由于它存储了文法,其他类都会用到Language类对象,Language类也定义了很多用于处理文法、语句的方法,供其他类调用。其中,很多方法都是基于可扩展的考虑。由于用例都是单个英文字母表示,没有用真实语言中的单词、语句这些来表示,所以为了今后的可扩展,预留了这些方法。
2.3.1 属性
public static String EmptyCharactor= "?"; //"?"表示“空”private String startCharactor; // 开始字符private boolean startSwitch= true; // 辅助记录开始字符privateLinkedHashMap<String, List<String>> grammar; // 存储文法规则的LinkedHashMap,键--非终结字符,值--候选式(列表)privateHashSet<String> terminalSet; // 终端字符集2.3.2 方法
public Language()public boolean addProduction(String sentence) // 给定一条语句添加文法public void changeProduction(String nonTerminal,List<String>rightParts) // 按产生式的左右两部分修改文法规则public void removeProduction(String nonTerminal)// 删除非终端字符参数所在的产生式publicSet<String> getNonTerminalSet() // 返回非终端字符集publicSet<String> getTerminalSet() // 返回终端字符集publicList<String> getRightPartsOfProduction(String nonTerminal) // 返回产生式的右部,即各候选式public boolean isTerminal(String charactor) // 判断是否是终端字符public void displayLanguage() // 输出文法规则public StringgetStartCharactor() // 返回开始字符public StringgetFirstWord(String sentence) // 返回候选式的首字符public StringgetLastWord(String sentence) // 返回候选式的末字符publicList<String> getEachWord(String sentence)// 返回候选式的每个字符2.4 LeftRecursive类
处理左递归。没有单独的去判断文法是否存在左递归,而是在消除左递归的过程中间接判断是否存在左递归。
2.4.1 属性
private Language language;public boolean doneRemove; // 标记是否存在左递归2.4.2 方法
publicLeftRecursive(Language language)private void removeLeftRecursive() // 消除文法中的左递归private boolean removeDirectLeftRecursive(String nonTerminal, List<String> newRightParts, Map<String,String> mapping) // 消除直接左递归private StringgetNewNonTerminal() // 得到一个新的非终结字符private void removeUnnecessary() // 清除多余的产生式2.5 FirstCollection类
处理FIRST集。主要是一个计算每个非终端字符FIRST集的setFirst方法和一个返回查询字符串的FIRST集的getFirst方法。
2.5.1 属性
private Language language;private final Map<String, Set<String>> firstCollection;// 存储各非终端字符的FIRST集,键--非终端字符,值--其FIRST集的字符集合2.5.2 方法
publicFirstCollection(Language language)private void initFirstCollection() /* 初始化FIRST集,就是给每个非终端字符调用setFirst方法,并将返回的集合保存到实例变量firstCollection */privateSet<String> setFirst(String word) // 求非终端字符的FIRST集publicSet<String> getFirst(String sentence)// 返回查询字符串的FIRST集2.6 FollowCollection类
处理FOLLOW集。其结构和FirstCollection类相同。
2.6.1 属性
private Language language;private FirstCollection firstCollection;private final Map<String, Set<String>> followCollection;// 存储各非终端字符的FOLLOW集,键--非终端字符,值--其FOLLOW集的字符集合2.6.2 方法
publicFollowCollection(Language language,FirstCollectionfirstCollection)private void initFollowCollection()privateSet<String> setFollow(String nonTerminal, String from)// 注意这里有个from参数,是为了防止无限的递归调用publicSet<String> getFollow(String nonTerminal)2.7 AnalysisTable类
存储LL(1)文法分析表,由此实现LL(1)分析器。
2.7.1 属性
private Language language;private FirstCollection firstCollection;private FollowCollectionfollowCollection;private Map<String,Map<String, String>> table; // LL(1)文法分析表,键--非终端字符,值--终端字符以及对应的候选式publicSet<String> columnSet;// LL(1)文法分析表的终端字符和句子终结符“#”privateStack<String> workStack = new Stack<String>(); // LL(1)分析器的分析栈privateStack<String> inputStack = new Stack<String>(); // 对读入的句子,也存在一个栈中2.7.2 方法
publicAnalysisTable(Language language, FirstCollectionfirstCollection, FollowCollection followCollection)private void initAnalysisTable() // 得到LL(1)文法分析表public void displayAnalysisTable() // 输出LL(1)文法分析表public boolean analyseSentence(String sentence) // 根据分析表分析输入的句子是否是该文法的句子,是的话返回trueprivate void displayStack(String option, Stringoutput) // 输出栈内容
源码+报告:DBank
- LL(1)分析器的Java实现
- LL(1)语法分析器 //c++实现
- LL(1)文法分析器简单实现
- LL(1)语法分析器 c++实现
- LL(1)语法分析器
- LL(1) 文法分析器
- 编译原理 实验2 语法分析器的构造 LL(1)
- LL语法分析器和LR语法分析器的比较
- java实现的简单词法分析器
- java实现简单的词法分析器
- 计算机编译原理习作——LL(1)语法分析器
- java实现词法分析器
- 用JAVA实现LL(1)文法语法分析程序
- 词法分析器的实现
- 词法分析器的实现
- 词法分析器的实现
- 一个简单词法分析器的实现代码(java实现)
- 一个简单词法分析器的实现代码(java实现)
- MyISAM 升级到 InnoDB
- 函数指针模拟多任务
- 算法实现——X和Y的中位数问题
- #ifndef、#def、#endif说明
- 多个DataTable的合并成一个新表
- LL(1)分析器的Java实现
- hdoj 3002 King of Destruction (最小割边集+Stoer-Wagner算法)
- ~~
- 《算法导论》于我何焉?
- 成员变量指针未初始化,异常处理对象析构
- ios 中获取udid的号码
- 4行代码计算9999的阶乘
- 十大音响品牌和十大假洋鬼子
- JavaScript换肤