基于MiniC的语义分析(使用javacc)
2017-12-25 22:30
267 查看
/********* WRITEN BY ZZG *********/ /******** DATE: 12,25,2017 *******/ /** * JJTree template file created by SF JavaCC plugin 1.5.28+ wizard for JavaCC 1.5.0+ */
//这是.jjt文件内容 options { static = true; } PARSER_BEGIN(MyNewGrammar) package test; import java.io.FileInputStream; import java.io.FileNotFoundException; import util.*; public class MyNewGrammar { public static void main(String args []) { FileInputStream fileStream; try { fileStream = new FileInputStream("test2.c"); //测试请在此处修改test1.c,test2.c,test3.c MyNewGrammar parser = new MyNewGrammar(fileStream); System.out.println("Reading from file ..."); try { SimpleNode rootNode = parser.Start(); rootNode.dump(" ");//抓取返回的语法树。 } catch (Exception e) { System.out.println("NOK."); System.out.println(e.getMessage()); } catch (Error e) { System.out.println("Oops."); System.out.println(e.getMessage()); } } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } PARSER_END(MyNewGrammar) SKIP : { " " | "\t" | "\n" | "\r" | < "//" (~[ "\n", "\r" ])* ( "\n" | "\r" | "\r\n" ) > | < "/*" (~[ "*" ])* "*" ( ~[ "/" ] (~[ "*" ])* "*" )* "/" > } TOKEN : { < CONSTANT: ( <DIGIT> )+("."(< DIGIT>)+)? > | < DIGIT: ["0" - "9"] > } TOKEN : /* LITERALS */ { < INTEGER_LITERAL : < DECIMAL_LITERAL > ([ "l", "L" ])? | < HEX_LITERAL > ([ "l", "L" ])? | < OCTAL_LITERAL > ([ "l", "L" ])? > | < #DECIMAL_LITERAL : [ "1"-"9" ] ([ "0"-"9" ])* > | < #HEX_LITERAL : "0" [ "x", "X" ] ([ "0"-"9", "a"-"f", "A"-"F" ])+ > | < #OCTAL_LITERAL : "0" ([ "0"-"7" ])* > } TOKEN : /* KEYWORDS */ { < MAIN : "main"> | < INT : "int"> | < FLOAT: "float" > | < VOID : "void"> | < IF:"if"> | < ELSE:"else" > | < WHILE:"while" > | < FOR:"for" > | < RETURN:"return"> } TOKEN : /* OPERATORS */ { < PLUS:"+"> | < MINUS:"-"> | < MULTIPLY:"*"> | < DIVIDE:"/"> | < ASSIGN:"="> } TOKEN : /* RELATIONSHIPOPERATOR */ { < LT:"<" > | < LE:"<=" > | < GT:">" > | < GE:"=>" > | < EQ:"==" > | < NE:"!=" > } TOKEN : /* IDENTIFIERS */ { < IDENTIFIER : < LETTER > ( < LETTER > | < DIGIT > )* > | < #LETTER : [ "_", "a"-"z", "A"-"Z" ] > } TOKEN: { <LC:"("> | <RC:")"> | <LM:"["> | <RM:"]"> | <LB:"{"> | <RB:"}"> } SimpleNode Start() : {} { Expression() { return jjtThis; } } void Expression() : {} { < INT >< MAIN >< LC >< RC >< LB > MainStatement() < RB > } void MainStatement():{} { Statement()//|(MainStatement())* } void Statement(): {QTTable qtTable=new QTTable(); } //qtTable应该在最前面声明,然后作为参数传递下去 { ( SequenceStatement(qtTable) //顺序语句 | IfStatement(qtTable) //条件语句 | While(qtTable) //循环语句 )* { QTInfo END=new QTInfo("","","",""); //结束 qtTable.addQTInfo(END); //qtTable.falseChain.add(END); qtTable.trueChain.add(END); qtTable.mergeFalseChain(); //回填假链 qtTable.mergeTrueChain(); //回填真链 qtTable.printQTTable(); //打印全局四元式 } } //顺序 void SequenceStatement(QTTable qtTable): { } { (declaration(qtTable)|copy(qtTable)) ";" //声明和赋值 } void declaration(QTTable qtTable) : { Token first,middle; Token eq=null; } { //每行定义一个数组,但可定义多个变量 (< INT>|< FLOAT>) middle=< IDENTIFIER> ( eq=< ASSIGN>first=< CONSTANT> { QTInfo qt=new QTInfo(eq.image,first.image,"_",middle.image); qtTable.addQTInfo(qt); } //这里只对声明的第一个赋值变量增加了语义子程序,若对后续赋值声明添加则需定义first和middle为Token数组 )? (","< IDENTIFIER >)* (< LM> < CONSTANT> < RM>)* //可声明多维 } void copy(QTTable qtTable): { String first; Token middle; Token eq=null; } { (middle=< IDENTIFIER>) (eq=< ASSIGN>) (first=expression(qtTable)) { QTInfo qt=new QTInfo(eq.image,first,"_",middle.image); qtTable.addQTInfo(qt); } } //条件 void IfStatement(QTTable qtTable):{String skipStr;QTInfo pre;} { < IF>< LC>Condition(qtTable)< RC> { pre=qtTable.getLastQt();} ( ( (assign(qtTable) ";") | (< LB> SequenceStatement(qtTable) {/*qtTable.trueChain.add(qtTable.getNextQt(pre));*/} < RB>) )/*{ qtTable.trueChain.add(qtTable.getLastQt());}*/ //真链跳转进入表达式时应该是该语句块的第一个语句的位置 ) { skipStr=VariableNameGenerator.genVariableName(); QTInfo qt1=new QTInfo("J","_","_",skipStr); qtTable.addQTInfo(qt1); qtTable.trueChain.add(qt1); }//条件为真执行完毕后跳转(跳过else语句块) ElseStatement(qtTable) } void ElseStatement(QTTable qtTable): { } { < ELSE> ((< LB> SequenceStatement(qtTable) < RB>)|IfStatement(qtTable)|assign(qtTable) ";") { qtTable.falseChain.add(qtTable.getLastQt()); } } //为使易于模块理解,copy()和assign()实则相同 void assign(QTTable qtTable): { String first; Token middle; Token eq=null; } { (middle=< IDENTIFIER>) (eq=< ASSIGN>) (first=expression(qtTable)) { QTInfo qt=new QTInfo(eq.image,first,"_",middle.image); qtTable.addQTInfo(qt); } } String Condition(QTTable qtTable) :{ String left,right,newTemp=null,falseStr,trueStr; Token rp; QTInfo pre;} { ( left=expression(qtTable) ( //<,<=,>,>=,==,!= (rp=< LT>|rp=< LE>|rp=< GT>|rp=< GE>|rp=< EQ>|rp=< NE>) right=expression(qtTable) { } ) { //qtTable.trueChain.add(qtTable.getLastQt()); //QTInfo pre=qtTable.getLastQt(); newTemp=VariableNameGenerator.genVariableName(); falseStr=VariableNameGenerator.genVariableName(); QTInfo qt1=new QTInfo("J"+rp.image,left,right,newTemp); qtTable.trueChain.add(qt1); //qtTable.trueChain.add(pre); QTInfo qt2=new QTInfo("J","_","_",falseStr); qtTable.falseChain.add(qt2); //QTInfo qt3=new QTInfo(""); qtTable.addQTInfo(qt1); qtTable.addQTInfo(qt2); } ) { return newTemp; } } String expression(QTTable qtTable): {String first,middle,newTemp; Token op; } { first=term(qtTable) {newTemp=first; }((op=< PLUS >|op=< MINUS >) middle=term(qtTable) { newTemp= VariableNameGenerator.genVariableName(); QTInfo qt=new QTInfo(op.image,first,middle,newTemp); qtTable.addQTInfo(qt); first=newTemp; })* { return newTemp; } } String term(QTTable qtTable): {String first,middle,newTemp; Token op; } { first=unary(qtTable) {newTemp=first; }(( op=< MULTIPLY >|op=< DIVIDE> ) middle=unary(qtTable) { newTemp=VariableNameGenerator.genVariableName(); QTInfo qt=new QTInfo(op.image,first,middle,newTemp); qtTable.addQTInfo(qt); first=newTemp; })* { return newTemp; } } String unary(QTTable qtTable) :{String str=null;Token token=null; } { ( token=< IDENTIFIER> { str=token.image; } | token=< CONSTANT> {str=token.image; }| (< LC>str=expression(qtTable)< RC>) ) { return str;} } //循环 void While(QTTable qtTable):{} { //支持赋值拷贝、四则运算、条件语句块、循环语句块的嵌套but目前只支持赋值语句,(#^_^#) < WHILE>< LC>Condition(qtTable)< RC>< LB>(copy(qtTable))*";"< RB> }
//这是QTTable的内容package util;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Iterator;
public class QTTable {
public ArrayList<QTInfo> QTList = new ArrayList<QTInfo>();
public ArrayList<QTInfo
4000
> falseChain=new ArrayList<QTInfo>();
public ArrayList<QTInfo> trueChain=new ArrayList<QTInfo>();
public static boolean flag = true;
public void addQTInfo(QTInfo info) {
QTList.add(info);
}
public void addQTInfo(int index, QTInfo info) {
QTList.add(index, info);
}
public QTInfo get(int index) {
return (QTInfo) QTList.get(index);
}
public QTInfo remove(int index) {
return QTList.remove(index - 1);
}
public void clear() {
QTList.clear();
QTInfo.innerIdSeqen = 0;
}
public void printQTTable() {
// System.out.println(toString());
Iterator<QTInfo> itr = QTList.iterator();
try {
File f = new File("result2.c"); //结果文件输出
if (f.exists()) {
} else {
f.createNewFile();// 不存在则创建
}
FileWriter output;
output = new FileWriter(f,false);
while (itr.hasNext()) {
QTInfo tmp = (QTInfo) itr.next();
output.write(tmp.toString()+"\n");
output.flush();
System.out.println(tmp.toString());
}
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public QTInfo getLastQt(){ //获取表中最后的一个元素
return get(QTList.size()-1);
}
public QTInfo getNextQt(QTInfo first){
Iterator<QTInfo> itr = QTList.iterator();
while(itr.hasNext()){
if(itr.next()==first)
return (QTInfo)itr.next();
}
return null;
}
public void mergeFalseChain(){ //回填假链
Iterator<QTInfo> itr=falseChain.iterator();
int count=0;
while(itr.hasNext()&&count<falseChain.size()-1){
QTInfo one = (QTInfo) itr.next();
//QTInfo next = (QTInfo) itr.next();
//此处需要得到下一个QTInfo但是又不能使itr的指针往下移
QTInfo next = falseChain.get(count++);
one.setResult(next.getInnerIdSeqen()-1);
}
/*Iterator<QTInfo> itr0=QTList.iterator();
while(itr0.hasNext()){
QTInfo temp0=(QTInfo) itr0.next();
itr=falseChain.iterator();
while(itr.hasNext()){
QTInfo temp=(QTInfo) itr.next();
if(temp0.getInnerIdSeqen()==temp.getInnerIdSeqen()){
temp0.setInnerId(temp.getInnerIdSeqen());
}
}
}*/
}
public void mergeTrueChain(){ //回填真链
Iterator<QTInfo> itr=trueChain.iterator();
int count=0;
while(itr.hasNext()&&count<trueChain.size()-1){
QTInfo one = (QTInfo) itr.next();
if(count==0){
one.setResult(4);
count++;
}else{
QTInfo next = trueChain.get(count++);
one.setResult(next.getInnerIdSeqen());
}
}
}
// public ArrayList<QTInfo> getQTList() {
// // TODO Auto-generated method stub
// return QTList;
// }
}
///这是QTInfo
package util; //定义四元式的信息 public class QTInfo { public static int innerIdSeqen = 0; // 四元式全局个数 private int innerId; // 当前四元式ID private String operator; private String arg1; private String arg2; private String result; public QTInfo(String operator, String arg1, String arg2, String result) { super(); this.innerId = ++innerIdSeqen; this.operator = operator; this.arg1 = arg1; this.arg2 = arg2; this.result = result; } public QTInfo(String operator, String arg1, String arg2, int result) { this(operator, arg1, arg2, result + ""); } public String getOperator() { return this.operator; } public void setResult(String result) { this.result = result; } public void setResult(int result) { this.result = "" + result; } public String getResult() { return this.result; } public void setInnerId(int innerID) { this.innerId = innerID; } public int getInnerIdSeqen() { return innerIdSeqen; } public String toString() { // TODO Auto-generated method stub return this.innerId + ":\t( " + this.operator + " \t" + this.arg1 + " \t" + this.arg2 + " \t" + this.result + " )"; } }最后,我想说的是->_-> :mmp,写完了才发现自己把某些自带的功能又实现了一遍。
相关文章推荐
- 使用javacc实现语法生成器(基于miniC语法)
- 使用JavaCC做语法分析
- S3C2440中断解析和基于WINCE操作系统的中断分析(整理于网络,用于按键中断使用)
- 使用递归下降算法分析数学表达式 -- 基于堆栈的计算器实现算法
- 读“基于明确语义分析的自动文摘算法”
- 基于visual c++之windows核心编程代码分析(56)使用winsock搜索蓝牙设备
- [ZZ]采访与书摘:使用C#进行基于模型的软件测试和分析
- 基于Java回顾之反射的使用分析
- 使用python构建基于hadoop的mapreduce日志分析平台 推荐
- 基于linux-2.6.38.8内核的SDIO/wifi驱动分析&&android 平台USB wifi驱动移植及使用 SDIOwifi
- 想做基于语义分析的移动搜索引擎,“出门问问”确认获得SIG领投的近千万美金B轮融资
- 基于webmagic的java网页爬虫,抓取网页指定节点,然后使用dom4j分析xml数据
- 使用python构建基于hadoop的mapreduce日志分析平台
- CENTOS6.3下使用Iptraf进行基于端口的网络流量的分析
- 基于visual c++之windows核心编程代码分析(52)使用WMI 获取进程启动参数
- 基于visual c++之windows核心编程代码分析(55)使用GoogleUrl方便安全地解析URL
- 使用python构建基于hadoop的mapreduce日志分析平台
- 基于visual c++之windows核心编程代码分析(52)使用WMI 获取进程启动参数
- 基于hprof的Android 内存使用分析
- WEB打印系列教程之一--基于Web的打印方案比较分析、使用IE的打印功能进行一般的网页打印