JavaCC语法分析实验二


JavaCC 语法分析实验二

一、实验目的:

  1. 掌握 JavaCC 语法分析器工作原理;
  2. 设计 MiniC 的上下文无关文法,在“Parser.jjt”文件中表示该文法,生
    成调试递归下降分析程序,以便对任意输入的符号串进行分析;
  3. 输出语法树。

二、MiniC 语法

〈程序〉 → int main() {〈语句块〉* }
〈语句块〉 →〈语句〉| {〈语句块〉* }
〈语句〉 →〈顺序语句〉|〈条件语句〉|〈循环语句〉
〈顺序语句〉→ (〈声明语句〉| 〈赋值语句〉) ”;” 〈声明语句〉→ int ID,ID,…,ID //思考如何表示
〈赋值语句〉→ ID =〈表达式〉
〈条件语句〉→ if (〈条件〉)〈语句块〉 else 〈语句块〉
〈循环语句〉→ while (〈条件〉)〈语句块〉
〈条件〉 →〈表达式〉〈关系符〉〈表达式〉
〈表达式〉 → // 可以使用javacc自动生成的 表达式(Expression)的文法
〈关系符〉 → <| <=| >| >= | ==| !=
注意:该文法为参考文法,可以对其适当修改。首先,文件中的文法必须
不含左递归和回溯;其次,同学们可以补充其它语法规则,如布尔表达式,for
语句等。

三、实习要求

  1. 以文件流的形式读入要分析的 C 语言程序;
  2. 如果输入的源程序符合 MiniC 的语法规范,输出语法树。
    扩展要求:具有错误检查的能力,可以输出错误所在的行号,并简单提
    示。

四、实验过程和指导:

  1. 新建一个用于 javacc 编辑的 jjt 模板文件:
    (1)新建 java 项目
    (2)建立一个语法分析包(例如:package parser)
    (3)在 parser 包内,“新建”-“其它”-“JavaCC Template File”
    (4)创建一个“.jjt”文件,如图 1 所示,建议选用“Non staitc”模式:
    图 1 新建 jjt 模板文件

  2. 在模板文件中修改词法部分和语法部分(如图 2 所示),将 MiniC 的文法依照要求写入 jjt 文件。

  3. 修改 jjt 文件的 main 方法(如图 2 所示),使其执行任务是:指定要进
    行语法分析的源程序,执行语法分析,输出语法树。
    在这里插入图片描述

五、程序输入/输出示例:

要求:测试多组源程序查看结果。
图 3 和图 4 为一组作为参考的测试源代码及其对应的语法树,具体的语法
树节点来自于同学们自定义的文法。
注意:文法的定义不同,语法树的层级关系则不同。
在这里插入图片描述
在这里插入图片描述

六.实验jjt源代码:

1.Start部分

impleNode Start() :
{}
{
  Program()
  {
    return jjtThis;
  }
}
 
void Program() :
{}
{
 < INT>
 < MAIN>
 < LBRACE>
 < RBRACE>
 < BLBRACE>
    (SentenceBlock())*
    (
      ReturnSent()
    )
 < BRBRACE>
}
 
void SentenceBlock():
{}
{
  Sentence()
| < BLBRACE>
(SentenceBlock())*
< BRBRACE>
}
 
void Sentence() :
{}
{
  SequenceSen()
  | ConditionSen()
  | LoopSent()
}
 
void SequenceSen() :
{}
{
   [
      AssigmentSen()
    | DeclareSen()
   ]
  < SEMICOLON>
}
 
void DeclareSen() :
{}
{
  [
       <INT>
   | <DOUBLE>
   | <FLOAT>
   | <CHAR>
  ]
   Identifier()
   (<COMMA> Identifier())*
}
 
void AssigmentSen() :
{}
{
  Identifier()
  <ASSIGN>
  Expression()
}
 
void ConditionSen() :
{}
{
  <IF>
   Condition()
   SentenceBlock()
}
 
void LoopSent() :
{}
{
  <WHILE>
  Condition()
  SentenceBlock()
}
 
void Condition() :
{}
{
  "("
  Expression()
  Relations()
  Expression()
  ")"
}
   
void Expression() :
{}
{
  AdditiveExpression()
}
 
void AdditiveExpression() :
{}
{
  MultiplicativeExpression()
  (
    (
      "+"
    | "-"
    )
    MultiplicativeExpression()
  )*
}
 
void MultiplicativeExpression() :
{}
{
  UnaryExpression()
  (
    (
      "*"
    | "/"
    | "%"
    )
    UnaryExpression()
  )*
}
 
void UnaryExpression() :
{}
{
  "(" Expression() ")"
| Identifier()
| Integer()
}
 
void Identifier() :
{}
{
  < IDENTIFIER >
}
 
void Integer() :
{}
{
  < INTEGER_LITERAL >
}
 
void Relations() :
{}
{
  <GT>
  | <LT>
  | <EQUAL>
}
 
void ReturnSent() :
{}
{
    < RETURN > <INTEGER_LITERAL> < SEMICOLON>
}

2.main方法部分

import java.io.FileReader;
import java.io.FileNotFoundException;
public class WorkGrammar
{
  public static void main(String args [])throws FileNotFoundException
  {
   System.out.println("语法分析");
   FileReader Fr = new FileReader("test3.txt"); 
    new WorkGrammar(Fr);
    try
    {
      SimpleNode n = WorkGrammar.Start();
      n.dump("");
      System.out.println("END");
    }
    catch (Exception e)
    {
      System.out.println("Oops.");
      System.out.println(e.getMessage());
    }
  }
}

3.源jjt代码

/**
 * JJTree template file created by SF JavaCC plugin 1.5.28+ wizard for JavaCC 1.5.0+
 */
options
{
  static = true;
}

PARSER_BEGIN(WorkGrammar)
package WorkGrammar;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class WorkGrammar
{
  public static void main(String args [])throws FileNotFoundException
  {
   System.out.println("语法分析");
   FileReader Fr = new FileReader("test.txt"); 
    new WorkGrammar(Fr);
    try
    {
      SimpleNode n = WorkGrammar.Start();
      n.dump("");
      System.out.println("END");
    }
    catch (Exception e)
    {
      System.out.println("Oops.");
      System.out.println(e.getMessage());
    }
  }
}

PARSER_END(WorkGrammar)


SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
| < "//" (~[ "\n", "\r" ])*
    (
      "\n"
    | "\r"
    | "\r\n"
    ) >
| < "/*" (~[ "*" ])* "*"
    (
      ~[ "/" ] (~[ "*" ])* "*"
    )*
    "/" >
}
TOKEN : /* KEYS */
{
  < INT : "int" >
| < DOUBLE : "double" >
| < FLOAT : "float" >
| < CHAR : "char" >
| < VOID : "void" >
| < FOR : "for" >
| < WHILE : "while" >
| < RETURN : "return" >
| < IF : "if" >
| 	< MAIN:"main">
}
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 : /* OPERATORS */
{
  < PLUS : "+" >
| < MINUS : "-" >
| < MULTIPLY : "*" >
| < DIVIDE : "/" >
| < ASSIGN : "=" >
| < GT : ">" >
| < LT : "<" >
| < EQUAL : "==" >
}

TOKEN : /* SEPARATER */
{
  < QUATION : "\"" >
| < SEMICOLON : ";" >
| < BLBRACE : "{" >
| < BRBRACE : "}" >
| < LBRACE : "(" >
| < RBRACE : ")" >
| < COMMA : "," >
| < EXCLA_SYM : "!" >
}
TOKEN : /* IDENTIFIERS */
{
  < IDENTIFIER :
    < LETTER >
    (
      < LETTER >
    | < DIGIT >
    )* >
| < #LETTER : [ "_", "a"-"z", "A"-"Z" ] >
| < #DIGIT : [ "0"-"9" ] >
}

SimpleNode Start() :
{}
{
  Program()
  {
    return jjtThis;
  }
}

void Program() :
{}
{
 < INT>
 < MAIN>
 < LBRACE>
 < RBRACE>
 < BLBRACE>
	(SentenceBlock())*
	(
	  ReturnSent()
	)
 < BRBRACE>
}

void SentenceBlock():
{}
{
  Sentence()
| < BLBRACE>
(SentenceBlock())*
< BRBRACE>
}

void Sentence() :
{}
{
  SequenceSen()
  | ConditionSen()
  | LoopSent()
}

void SequenceSen() :
{}
{
   [
      AssigmentSen()
    | DeclareSen()
   ]
  < SEMICOLON>
}

void DeclareSen() :
{}
{
  [
  	 <INT>
   | <DOUBLE>
   | <FLOAT>
   | <CHAR>
  ]
   Identifier()
   (<COMMA> Identifier())*
}

void AssigmentSen() :
{}
{
  Identifier()
  <ASSIGN>
  Expression()
}

void ConditionSen() :
{}
{
  <IF>
   Condition()
   SentenceBlock()
}

void LoopSent() :
{}
{
  <WHILE>
  Condition()
  SentenceBlock()
}

void Condition() :
{}
{
  "("
  Expression()
  Relations()
  Expression()
  ")"
}
  
void Expression() :
{}
{
  AdditiveExpression()
}

void AdditiveExpression() :
{}
{
  MultiplicativeExpression()
  (
    (
      "+"
    | "-"
    )
    MultiplicativeExpression()
  )*
}

void MultiplicativeExpression() :
{}
{
  UnaryExpression()
  (
    (
      "*"
    | "/"
    | "%"
    )
    UnaryExpression()
  )*
}

void UnaryExpression() :
{}
{
  "(" Expression() ")"
| Identifier()
| Integer()
}

void Identifier() :
{}
{
  < IDENTIFIER >
}

void Integer() :
{}
{
  < INTEGER_LITERAL >
}

void Relations() :
{}
{
  <GT>
  | <LT>
  | <EQUAL>
}

void ReturnSent() :
{}
{
	< RETURN > <INTEGER_LITERAL> < SEMICOLON>
}

七.实验结果

//实验测试一
int main(){
    int a,b;
    a = 23;
   while(a>2){
       int x;
       x = a+b;     
   }
   return 0;
}

在这里插入图片描述

//实验测试二
int main(){
    int a,b;
    a=1;
    b=3;
   if(a<b){
       int x;
       x = a;
       a = b;
       b = x;     
   }
   return 0;
}

在这里插入图片描述

  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值