javacc 语义分析
在词法和语法分析的基础上添加语义子程序,并且掌握“拉链”、“回填”操作的原理以及实现;并且针对测试代码,输出四元式序列。
仍然是使用和语法分析相同的MiniC语法作为参考文法。
<程序> ->Type main(){<语句块>*}
<语句块> -> <语句>|{<语句块>*}
<语句> -> <顺序语句>|<条件语句>|<循环语句>
<顺序语句> ->(<声明语句>|<赋值语句>)”;”
<声明语句> ->Type ID,ID,…,ID
<赋值语句> ->ID =<表达式>
<条件语句> ->if(<条件>)<语句块>else<语句块>
<循环语句> ->while(<条件>)<语句块>
<逻辑> -><条件>(<逻辑运算符><条件>)*
<条件> -><表达式>(<关系符><表达式>)?
<表达式> ->//可以使用默认的
<关系符> -><|<=|>|>=|==|!=
<逻辑运算> ->&& | || (包含在逻辑中)
修改.jjt文件中的main方法,使其执行任务是:指定要进行语义分析的源程序,执行语义分析,输出四元式到文件中。
要想好编译程序的结构,除了JavaCC生成的类,还需要哪些辅助类。如四元式类、四元式链表类、自动产生临时变量的类等。这里的四个类都可以使用所给的类,直接添加到项目进行使用。
为了使得输出的四元式子在文件中而不输出语法树,我们可以选择将QTList类中的printQTTable方法进行修改。
?public void printQTTable() {
? // System.out.println(toString());
? Iterator<QTInfo> itr = QTList.iterator();
? try {
? FileWriter fw = new FileWriter("./result.txt",true);
? BufferedWriter bw = new BufferedWriter(fw);
? while (itr.hasNext()) {
? QTInfo tmp = (QTInfo) itr.next();
? //System.out.println(tmp.toString());
? bw.write(tmp.toString());
? bw.newLine();
? }
? bw.close();
? fw.close();
?
? } catch (Exception e) {
? e.printStackTrace();
? }
? }
?
在.jjt文件中添加Minic文法表达式
?SimpleNode Start() :
?{}
?{
? ?Program()
? ?//AdditiveExpression()
? {
? ? ?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() ://赋值语句
?{
? ?String str2=null,str1=null;
? ?Token op;
?}
?{
? ?str1 = Identifier()
? ?op = "="
? ?str2 = Expression()
? {
? ? ?QTInfo qt = new QTInfo(op.image,str2,"_",str1);
? ? ?qtList.addQTInfo(qt);
? }
?}
??
??
??
??
?void ConditionSentence()://条件语句
?{
? ?int QTSize = QTInfo.size;
? ?ConditionValue Value = null;
?}
?{
? ?< IF >< LB >
? (
? ?Value = ifCondition()
? )
? ?< RB >
? {
? ? ?Value.backpatchTrueChain(QTInfo.size+1);
? }
? ?SentenceBlock()
? {
? Value.backpatchFalseChain(QTInfo.size+1);
? }
? (
? ?
? ? ?< ELSE >
? {
? QTInfo qt = new QTInfo("J","_","_","T");
? qtList.addQTInfo(qt);
? Value.mergeTrue(qt);
? ? }
? ?SentenceBlock()
? ? {
? ? ? ?Value.backpatchTrueChain(QTInfo.size+1);
? ? ? ?Value.backpatchFalseChain(QTInfo.size);
? ?
? ? }
? )?
?}
?ConditionValue Condition() ://循环条件
?{
? ConditionValue Value = new ConditionValue();
? String str1 = null,str2 = null;
? Token op = null;
?}
?{
? ?str1 = Expression()(
? ? (
? ? ?op = ">"
? ?|op = "<"
? ?|op = ">="
? ?|op = "<="
? ?|op = "!="
? ?|op = "||"
? ?|op = "&&"
? )
? ?
? ? ?str2 = Expression())?
?{
? ?QTInfo qt1 = new QTInfo("J"+op.image,str1,str2,"_");
? ?qtList.addQTInfo(qt1);
? ?QTInfo qt2 = new QTInfo("J","_","_","_");
? ?qtList.addQTInfo(qt2);
? ?Value.mergeTrue(qt1);
? ?Value.mergeFalse(qt2);
? ?return Value;
?// QTInfo qt1;
?// if(str2 != "")
?// qt1 = new QTInfo("J"+op.image,str1,str2,"_");
?// else
?// ? qt1 = new QTInfo("Jnz",str1,"_","_");
?// qtList.addQTInfo(qt1);
?// QTInfo qt2 = new QTInfo("J","_","_","_");
?// qtList.addQTInfo(qt2);
?// Value.mergeTrue(qt1);
?// Value.mergeFalse(qt2);
?// return Value;
?}
?}
?ConditionValue ifCondition() ://判定条件
?{
? ConditionValue Value = new ConditionValue();
? String str1 = null,str2 = null;
? Token op = null;
? int qtSize = QTInfo.size;
?}
?{
? ?str1 = Expression()(
? ? (
? ? ?op = ">"
? ?|op = "<"
? ?|op = ">="
? ?|op = "<="
? ?|op = "!="
? ?|op = "||"
? ?|op = "&&"
? )
? ?
? ? ?str2 = Expression())?
?{
??
? ?QTInfo qt1;
? ?
? ?if(op != null) {
? qt1 = new QTInfo("J"+op.image,str1,str2,QTInfo.size+3);
? qtList.addQTInfo(qt1);
? ? ?//Value.mergeTrue(qt1);
? }
? ?else {
? ? ?qt1 = new QTInfo("Jnz",str1,"_",QTInfo.size+3);
? ? ?qtList.addQTInfo(qt1);
? ? ?//Value.mergeTrue(qt1);
? }
? ?
? ?QTInfo qt2 = new QTInfo("J","_","_","F");
? ?qtList.addQTInfo(qt2);
? ?
? ?Value.mergeFalse(qt2);
? ?return Value;
?}
?}
?void LoopSentence()://循环语句
?{
? ?int QTSize = QTInfo.size;
? ?ConditionValue Value = null;
?}
?{
? < WHILE >
? < LB >
? Value = Condition()
? < RB >
? {
? Value.backpatchTrueChain(QTInfo.size+1);
? }
? SentenceBlock()
? {
? ?QTInfo qt = new QTInfo("J","_","_",QTSize+1);
? ?qtList.addQTInfo(qt);
? ?Value.backpatchFalseChain(QTInfo.size+1);
? }
?}
?String Expression() ://表达式
?{String str;}
?{
? str = AdditiveExpression()
? {
? ? return str;
? }
?}
??
?String AdditiveExpression() :
?{
? ?String str1,str2;
? ?String newTemp;
? ?Token op;
?}
?{
? ?str1 = MultiplicativeExpression()
? {
? ? ?newTemp = str1;
? }
? (
? ? (
? ? ? ?op = "+"
? ? ?| op = "-"
? ? )
? ?str2 = MultiplicativeExpression()
? {
? ? ?newTemp = VariableNameGenerator.genVariableName();
? ? ?QTInfo qt = new QTInfo(op.image,str1,str2,newTemp);
? ? ?qtList.addQTInfo(qt);
? ? ?str1 = newTemp;
? }
? )*
? {
? ? ?return newTemp;
? }
?}
??
?String MultiplicativeExpression() :
?{
? ?String str1,str2;
? ?String newTemp;
? ?Token op;
?}
?{
? ?str1 = UnaryExpression()
? {
? ? ?newTemp = str1;
? }
? (
? ? (
? ? ? ?op = "*"
? ? ?| op = "/"
? ? ?| op = "%"
? ? )
? ?str2 = UnaryExpression()
? {
? ? ?newTemp = VariableNameGenerator.genVariableName();
? ? ?QTInfo qt = new QTInfo(op.image,str1,str2,newTemp);
? ? ?qtList.addQTInfo(qt);
? ? ?str1 = newTemp;
? }
? )*
? {
? ? ?return newTemp;
? }
?}
??
?String UnaryExpression() :
?{String str = null;}
?{
? (
?
? "(" str = Expression() ")"
? | str = Identifier()
? | str = Integer()
? | str = Constant()
? )
? {
? ?return str;
? }
?}
??
??
?String Identifier() :
?{Token t = null;}
?{
? ?t = < IDENTIFIER >
? {
? ? ?return t.image;
? }
?}
??
?String Integer() :
?{Token t = null;}
?{
? ?t = < INTEGER_LITERAL >
? {
? ? ?return t.image;
? }
?}
?String Constant() :
?{Token t =null;}
?{
? ?t = < CONSTANT >
? {
? ? ?return t.image;
? }
?}
测试代码和生成的四元式如下:
?
?
?
完整的jjt文件如下:
?/**
? * JJTree template file created by SF JavaCC plugin 1.5.28+ wizard for JavaCC 1.5.0+
? */
?options
?{
? ?static = true;
?}
??
?PARSER_BEGIN(MyNewGrammar)
?package byylworkform3;
?import utils.*;
?import java.io.FileInputStream;
?public class MyNewGrammar
?{
? ?static QTList qtList = new QTList();
? ?public void printQTList() {
? qtList.printQTTable();
? }
? ?public static void main(String args [])
? {
?// ? System.out.println("Reading from standard input...");
?// ? System.out.print("Enter an expression like \"1+(2+3)*var;\" :");
?// ? MyNewGrammar input = new MyNewGrammar(System.in);
? ? ?try
? ? {
? ? ? ?//String file = "./text1.txt";
? ? ? ?String file = "./text2.txt";
? ? ? ?//String file = "./text3.txt";
? ? ? ?//String file = "./text4.txt";
? ? ? ?FileInputStream fin = new FileInputStream(file);
? ? ? ?MyNewGrammar input = new MyNewGrammar(fin);
? ? ? ?SimpleNode n = MyNewGrammar.Start();
? ? ? ?input.printQTList();
? ? ? ?n.dump("");
? ? ? ?System.out.println("Thank you.");
? ? }
? ? ?catch (Exception e)
? ? {
? ? ? ?System.out.println("Oops.");
? ? ? ?System.out.println(e.getMessage());
? ? }
? }
?}
??
?PARSER_END(MyNewGrammar)
??
?SKIP :
?{
? ?" "
?| "\t"
?| "\n"
?| "\r"
?| < "//" (~[ "\n", "\r" ])*
? ? (
? ? ? ?"\n"
? ? ?| "\r"
? ? ?| "\r\n"
? ? ) >
?| < "/*" (~[ "*" ])* "*"
? ? (
? ? ? ?~[ "/" ] (~[ "*" ])* "*"
? ? )*
? ? ?"/" >
?}
??
?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 :
?{
? ?< CONSTANT :
? ? (< DIGIT >)+
? ? (
? ? ? ?"." (< DIGIT >)+
? ? )? >
?}
??
?TOKEN : /* KEYWORDS */
?{
? < MAIN : "main" >
?| < INT : "int" >
?| ?< RETURN :"return" >
?| < IF:"if" >
?| < ELSE:"else" >
?| < VOID : "void" >
?| < DOUBLE:"double" >
?| < FLOAT:"float" >
?| < WHILE:"while" >
?| < DO:"do" >
?| < FOR:"for" >
?| < CHAR:"char" >
?| < STRING:"string" >
?| < BOOL:"bool" >
?}
??
?TOKEN: /*OPERATORS*/
?{
? < PLUS : "+" >
?| < MINUS : "-" >
?| < MULTIPLY : "*" >
?| < DIVIDE : "/" >
?| < GD:">" >
?| < LD:"<" >
?| < SQRT:"^" >
?| < EQ:"=" >
?| < GE:">=" >
?| < LE:"<=" >
?| < EQQ:"==" >
?| < NE:"!=" >
?| < ANDD:"&&" >
?| < ORR:"||" >
?}
?TOKEN: /* SEPARATER */
?{
?< COMMA:"," >
?| < SEMICOLON:";" >
?| < LB:"(" >
?| < RB:")" >
?| < BLB:"{" >
?| < BRB:"}" >
?| < LBB:"[" >
?| < RBB:"]" >
??
?}
?TOKEN : /* IDENTIFIERS */
?{
? ?< IDENTIFIER :
? ? ?< LETTER >
? ? (
? ? ? ?< LETTER >
? ? ?| < DIGIT >
? ? )* >
?| < #LETTER : [ "_", "a"-"z", "A"-"Z" ] >
?| < #DIGIT : [ "0"-"9" ] >
?}
??
?SimpleNode Start() :
?{}
?{
? ?Program()
? ?//AdditiveExpression()
? {
? ? ?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() ://赋值语句
?{
? ?String str2=null,str1=null;
? ?Token op;
?}
?{
? ?str1 = Identifier()
? ?op = "="
? ?str2 = Expression()
? {
? ? ?QTInfo qt = new QTInfo(op.image,str2,"_",str1);
? ? ?qtList.addQTInfo(qt);
? }
?}
??
??
??
??
?void ConditionSentence()://条件语句
?{
? ?int QTSize = QTInfo.size;
? ?ConditionValue Value = null;
?}
?{
? ?< IF >< LB >
? (
? ?Value = ifCondition()
? )
? ?< RB >
? {
? ? ?Value.backpatchTrueChain(QTInfo.size+1);
? }
? ?SentenceBlock()
? {
? Value.backpatchFalseChain(QTInfo.size+1);
? }
? (
? ?
? ? ?< ELSE >
? {
? QTInfo qt = new QTInfo("J","_","_","T");
? qtList.addQTInfo(qt);
? Value.mergeTrue(qt);
? ? }
? ?SentenceBlock()
? ? {
? ? ? ?Value.backpatchTrueChain(QTInfo.size+1);
? ? ? ?Value.backpatchFalseChain(QTInfo.size);
? ?
? ? }
? )?
?}
?ConditionValue Condition() ://循环条件
?{
? ConditionValue Value = new ConditionValue();
? String str1 = null,str2 = null;
? Token op = null;
?}
?{
? ?str1 = Expression()(
? ? (
? ? ?op = ">"
? ?|op = "<"
? ?|op = ">="
? ?|op = "<="
? ?|op = "!="
? ?|op = "||"
? ?|op = "&&"
? )
? ?
? ? ?str2 = Expression())?
?{
? ?QTInfo qt1 = new QTInfo("J"+op.image,str1,str2,"_");
? ?qtList.addQTInfo(qt1);
? ?QTInfo qt2 = new QTInfo("J","_","_","_");
? ?qtList.addQTInfo(qt2);
? ?Value.mergeTrue(qt1);
? ?Value.mergeFalse(qt2);
? ?return Value;
?// QTInfo qt1;
?// if(str2 != "")
?// qt1 = new QTInfo("J"+op.image,str1,str2,"_");
?// else
?// ? qt1 = new QTInfo("Jnz",str1,"_","_");
?// qtList.addQTInfo(qt1);
?// QTInfo qt2 = new QTInfo("J","_","_","_");
?// qtList.addQTInfo(qt2);
?// Value.mergeTrue(qt1);
?// Value.mergeFalse(qt2);
?// return Value;
?}
?}
?ConditionValue ifCondition() ://判定条件
?{
? ConditionValue Value = new ConditionValue();
? String str1 = null,str2 = null;
? Token op = null;
? int qtSize = QTInfo.size;
?}
?{
? ?str1 = Expression()(
? ? (
? ? ?op = ">"
? ?|op = "<"
? ?|op = ">="
? ?|op = "<="
? ?|op = "!="
? ?|op = "||"
? ?|op = "&&"
? )
? ?
? ? ?str2 = Expression())?
?{
??
? ?QTInfo qt1;
? ?
? ?if(op != null) {
? qt1 = new QTInfo("J"+op.image,str1,str2,QTInfo.size+3);
? qtList.addQTInfo(qt1);
? ? ?//Value.mergeTrue(qt1);
? }
? ?else {
? ? ?qt1 = new QTInfo("Jnz",str1,"_",QTInfo.size+3);
? ? ?qtList.addQTInfo(qt1);
? ? ?//Value.mergeTrue(qt1);
? }
? ?
? ?QTInfo qt2 = new QTInfo("J","_","_","F");
? ?qtList.addQTInfo(qt2);
? ?
? ?Value.mergeFalse(qt2);
? ?return Value;
?}
?}
?void LoopSentence()://循环语句
?{
? ?int QTSize = QTInfo.size;
? ?ConditionValue Value = null;
?}
?{
? < WHILE >
? < LB >
? Value = Condition()
? < RB >
? {
? Value.backpatchTrueChain(QTInfo.size+1);
? }
? SentenceBlock()
? {
? ?QTInfo qt = new QTInfo("J","_","_",QTSize+1);
? ?qtList.addQTInfo(qt);
? ?Value.backpatchFalseChain(QTInfo.size+1);
? }
?}
?String Expression() ://表达式
?{String str;}
?{
? str = AdditiveExpression()
? {
? ? return str;
? }
?}
??
?String AdditiveExpression() :
?{
? ?String str1,str2;
? ?String newTemp;
? ?Token op;
?}
?{
? ?str1 = MultiplicativeExpression()
? {
? ? ?newTemp = str1;
? }
? (
? ? (
? ? ? ?op = "+"
? ? ?| op = "-"
? ? )
? ?str2 = MultiplicativeExpression()
? {
? ? ?newTemp = VariableNameGenerator.genVariableName();
? ? ?QTInfo qt = new QTInfo(op.image,str1,str2,newTemp);
? ? ?qtList.addQTInfo(qt);
? ? ?str1 = newTemp;
? }
? )*
? {
? ? ?return newTemp;
? }
?}
??
?String MultiplicativeExpression() :
?{
? ?String str1,str2;
? ?String newTemp;
? ?Token op;
?}
?{
? ?str1 = UnaryExpression()
? {
? ? ?newTemp = str1;
? }
? (
? ? (
? ? ? ?op = "*"
? ? ?| op = "/"
? ? ?| op = "%"
? ? )
? ?str2 = UnaryExpression()
? {
? ? ?newTemp = VariableNameGenerator.genVariableName();
? ? ?QTInfo qt = new QTInfo(op.image,str1,str2,newTemp);
? ? ?qtList.addQTInfo(qt);
? ? ?str1 = newTemp;
? }
? )*
? {
? ? ?return newTemp;
? }
?}
??
?String UnaryExpression() :
?{String str = null;}
?{
? (
?
? "(" str = Expression() ")"
? | str = Identifier()
? | str = Integer()
? | str = Constant()
? )
? {
? ?return str;
? }
?}
??
??
?String Identifier() :
?{Token t = null;}
?{
? ?t = < IDENTIFIER >
? {
? ? ?return t.image;
? }
?}
??
?String Integer() :
?{Token t = null;}
?{
? ?t = < INTEGER_LITERAL >
? {
? ? ?return t.image;
? }
?}
?String Constant() :
?{Token t =null;}
?{
? ?t = < CONSTANT >
? {
? ? ?return t.image;
? }
?}
??
|