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;
}
}