javacc 语法分析
在词法分析的基础上使用给出的MiniC语法为参考文法编写语法分析器。
MiniC语法如下:
<程序> ->Type main(){<语句块>*}
<语句块> -> <语句>|{<语句块>*}
<语句> -> <顺序语句>|<条件语句>|<循环语句>
<顺序语句> ->(<声明语句>|<赋值语句>)”;”
<声明语句> ->Type ID,ID,…,ID
<赋值语句> ->ID =<表达式>
<条件语句> ->if(<条件>)<语句块>else<语句块>
<循环语句> ->while(<条件>)<语句块>
<逻辑> -><条件>(<逻辑运算符><条件>)*
<条件> -><表达式>(<关系符><表达式>)?
<表达式> ->//可以使用默认的
<关系符> -><|<=|>|>=|==|!=
<逻辑运算> ->&& | || (包含在逻辑中)
要求如下:以文件流的形式读入要分析的C语言程序;如果输入的源程序符合MiniC的语法规范,输出语法树到文件中。
程序的输入需要从文件中读取,并且我们需要修改SimpleNode.java文件中的dump方法来使得输出语法树到指定文件中。
SimpleNode.java文件中的dump方法修改部分如下:
public void dump(String prefix) { try { File file = new File("./text2.txt"); FileOutputStream out = new FileOutputStream(file,true); byte [] array = (toString(prefix)+"\n").getBytes(); out.write(array); out.close(); if (children != null) { for (int i = 0; i < children.length; ++i) { SimpleNode n = (SimpleNode)children[i]; if (n != null) { n.dump(prefix + " "); } } } }catch(Exception e) { e.printStackTrace(); }
.jjt文件中Main方法修改为:
import java.io.FileInputStream; import java.io.FileReader; import java.io.FileNotFoundException; public class MyNewGrammar { public static void main(String args [])throws FileNotFoundException { System.out.println("语法分析Reading from standard input..."); FileReader fr = new FileReader("./workform.txt"); MyNewGrammar parser = new MyNewGrammar(fr); try { SimpleNode n = parser.Start(); n.dump(""); System.out.println("END"); }catch (Exception e){ System.out.println("Oops."); System.out.println(e.getMessage()); } } }
.jjt文件中添加实现的语法规则如下:
SimpleNode Start() : {} { Program() { return jjtThis; } } void Program() : {} { Type() < MAIN > < LB > < RB > < BLB > ( SentenceBlock() )* (ReturnSentence() ) < BRB > } void Type() : {} { < INT > | < VOID > | < STRING > | < CHAR > | < DOUBLE > | < FLOAT > } void ReturnSentence(): {} { < RETURN > <INTEGER_LITERAL> < SEMICOLON> } void SentenceBlock() : {} { Sentence() | < BLB > (SentenceBlock())* < BRB > } void Sentence() : {} { SequenceSentence() | ConditionSentence() | LoopSentence() } void SequenceSentence() : {} { StateSentence() < SEMICOLON > | AssignSentence() < SEMICOLON > } void StateSentence() : {} { Type() Identifier() (< COMMA > Identifier())* } void AssignSentence() : {} { Identifier() < EQ > Expression() } void ConditionSentence(): {} { < IF > Condition() SentenceBlock() } void Condition() : {} { < LB > Expression() Relations() Expression() < RB > } void Relations(): {} { < GD > | < LD > | < EQ > } void LoopSentence(): {} { < WHILE > Condition() SentenceBlock() }
测试代码如下:
void main() { while(a>45){ int x, x1; x=x1+1; } return 0; }
结果如下: