`
Anddy
  • 浏览: 197942 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

cmm编译器-cmm 语言语法分析-javacc实现

    博客分类:
  • java
阅读更多

Cmm的文法:

//程序开始

programàstmt-sequence

stmt-sequenceà statement | statement; stmt-squence

//各种语句的文法

statementàif-stmt | while-stmt | read-stmt | write-stmt|assign-stmt| declare-stmt

//LL1

Sàstmt

Stmtàif-stmt morestmt|while-stmt morestmt |read-stmt morestmt |write-stmt morestmt |assign-stmt morestmt |declare-stmt morestmt

Morestmtà$ |stmt

T: ε

//变量数组声明语句文法

declare-stmtà(int | real |int[] |real[] ) indentifier |(int | real |int[] |real[] )  identifier indetifierMuti;

indetifierMutià,identifier| ,identifier idetifierMuti

//LL1

Declare-stmtàint more identifier more-declare| real more identifier more-declare 

more-->ε | []

More-declareà; | ,identifier more-declare

//if语句

if-stmtàif ( exp ) {stmt-sequence} ­

| if ( exp ) {stmt-sequence} elseifelse-stmt

elseifelse-stmtà else if ( exp ) {stmt-sequence} elseifelse-stmt | else  {stmt-sequence}

LL1

If-stmtàif ( exp ) { stmt } more-ifelse

more-ifelse àε | else else-stmt

else-stmtàif { stmt } |{ stmt }

//while语句

while-stmtàwhile (exp){stmt-sequence}

LL1

While-stmtàwhile(exp){stmt}

//read语句

read-stmtàread identifier

LL1

Read-stmtàread identifier ;

//write语句

write-stmtàwrite exp

LL1

Write-stmt àwrite exp ;

 

//赋值语句

assign-stmtàidentifier = exp|identifier[number]=exp

LL1

Assign-stmtàidentifier other-assign

Other-assignà=exp; | [number]=exp;

//表达式

expàsimple-exp comparison-op simple-exp | simple-exp

LL1

Expàsimple-exp more-exp

More-expàε|comparison-op simple-exp

 

//比较符

comparison-opà< | == | <>

LL1

comparison-opà< | == | <>

 

//加减操作表达式

simple-expàsimple-exp add-op term| term

LL1

Simple-expàterm more-term

More-termàε | add-op term more-term

//运算符

add-opà+|-

LL1

Add-opà+|-

//乘除操作表达式

termàterm mul-op factor | factor

LL1

Termàfactor more-factor

More-factoràε | mul-op factor more-factor

//乘除运算符

mul-opà*|/

LL1

mul-opà*|/

//因子

factorànumber|identifier|(exp)| identifier[number]

LL1

Factorànumber|identifier more-identifier|(exp)

more-identifieràε | [number]

 number → number-real | number-int

 

 

 

 

 

测试列表

注明:测试类对于正确语法的cmm源程序输出 cmm源码语法分析成功,更不会有任何的异常抛出。但是对于错误语法的cmm源程序,这个界面程序将告诉你“cmm源码语法分析失败

 

测试1

测试cmm源码:

int i; i=1;if(i==1){ read i;}else{read i;}

测试的Testeg1.java程序部分如下:

String str ="int i; " +                                   

           "i=1;if(i==1)" +                                

           "{ read i;}" +                                  

           "else" +                                         

           "{read i;}";                                    

      eg1 parser = new eg1(new StringReader(str));      

   parser.program(); 

  

 

测试结果:通过,无任何异常抛出!

测试2     

测试cmm源码:

/*测试数组和变量声明*/int i_3[],i;i=1;/**测试while*/while(i==2){i=2;}/*测试表达式*/i=2*(3+4);

测试的Testeg1.java部分代码如下

String str ="/**测试数组" +"*/"+

         "int i_3[],i;i=1;" +

         "/**测试while*/ " +

         "while(i==2){i=2;}" +

         "i=2*(3+4);"; 

     eg1 parser = new eg1(new StringReader(str));

     parser.program(); 

 

 

测试结果:通过,无任何异常抛出!

测试2     

测试cmm源码:

//测试数组的赋值以及数组参与运算

i_3[2]=0;i=i_3[1]+2;

试结果:通过,无任何异常抛出!

 

 Javacc 语法分析

遇到的问题:

问题1

第一次写的cmm语法含有左递归:而Javacc不支持左递归,于是把左递归换成右递归,比如:

stmt-sequenceà stmt-squence ; statement | statement

改成如下形式:

stmt-sequenceà statement | statement; stmt-squence 对应javacc中的写法如下:

void stmt_sequence() : {}

{

   statement()

   (

     < SEMICOLON > stmt_sequence()

)*

 

}

但是又出现了新的警告信息,如下描述:

Warning: Choice conflict in (...)* construct

原因不是很明白,但是通过交流只知道怎么解决这个问题,

Javaccoptions设置中添加如下语句:

LOOKAHEAD =2 ; 就解决了问题。

 

问题2

测试如下cmm源码时

/**测试*/int i_3[],i;i=1;/**测试while*/while(i==2){i=2;}i=2*(3+4);

出现如下错误:

Exception in thread "main" exercise.grammer.ParseException: Encountered " ";" "; "" at line 1, column 21.

Was expecting:

"," ...

根据错误提示为:期望的是逗号。问题在声明语句;查看declare_stmt 的代码

void declare_stmt():{}

{

  < INT > < IDENTIFIER >

  (

    <LBRACKET ><RBRACKET >

  )?

  (

    idetifierMutil()

  )?<SEMICOLON >

 

|   < REAL >< IDENTIFIER >

(

  <LBRACKET ><RBRACKET >

)?

(

  idetifierMutil()

)?<SEMICOLON >

 

}

void idetifierMutil():{}

{

  < COMMA > <IDENTIFIER >

  (

    <LBRACKET ><RBRACKET >

  )?idetifierMutil()

}

将其更改为如下:

void declare_stmt():{}

{

 

  < INT > < IDENTIFIER >

  (

    <LBRACKET ><RBRACKET >

  )?

  (

    idetifierMutil()

  )*<SEMICOLON >

 

|   < REAL >< IDENTIFIER >

(

  <LBRACKET ><RBRACKET >

)?

(

  idetifierMutil()

)*<SEMICOLON >

 

}

void idetifierMutil():{}

{

  < COMMA > <IDENTIFIER >

  (

    <LBRACKET ><RBRACKET >

  )?

}

于是把声明变量和声明数组的问题解决!

 

问题3

在测试数组过程中.

测试cmm代码: i_3[2]=0;i=i_3[1]+2;

抛出如下异常:

Exception in thread "main" exercise.grammer.ParseException: Encountered " "[" "[ "" at line 1, column 15.

Was expecting:

    ";" ...

i_3[1]这个位置出错了。原因在数组参与运算

Cmm文法

factorànumber|identifier|(exp)| identifier[number]

对应的javacc代码修改为如下:

void factor():{}

{

  < INT_LITERAL >

| < REAL_LITERAL>

| < IDENTIFIER >

(

  < LBRACKET > < INT_LITERAL > < RBRACKET >

)?

| < LPAREN > exp() < RPAREN >

 

}

 

重新测试,通过.

 

加上javacc源码:

 

/**
 * JavaCC file
 */
 
options {
  JDK_VERSION = "1.5";
  LOOKAHEAD = 2 ;
  FORCE_LA_CHECK =false;
}
PARSER_BEGIN(eg1)
package exercise.grammer;

public class eg1 {
 public static void main(String args[]) throws ParseException {
    eg1 parser = new eg1(System.in);
     try {
        switch (eg1.program()) {
        case 0:
          System.out.println("OK.");
          break;
        default:
          System.out.println("Goodbye.");
          break;
    }
      } catch (Exception e) {
        System.out.println("NOK.");
        System.out.println(e.getMessage());
        eg1.ReInit(System.in);
      } catch (Error e) {
        System.out.println("Oops.");
        System.out.println(e.getMessage());
       
      }
  
  }
}
PARSER_END(eg1)
SKIP :
{
 
  " "
| "\t"
| "\n"
| "\r"
| "\f"

}
/* COMMENT */
MORE :
{
  "//" : IN_SINGLE_LINE_COMMENT
|
  <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
|
  "/*" : IN_MULTI_LINE_COMMENT
}

<IN_SINGLE_LINE_COMMENT>
SPECIAL_TOKEN :
{
  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT
}

<IN_FORMAL_COMMENT>
SPECIAL_TOKEN :
{
  <FORMAL_COMMENT: "*/" > : DEFAULT
}

<IN_MULTI_LINE_COMMENT>
SPEC

  


  
分享到:
评论

相关推荐

    javacc实现cmm语法分析

    下面我们将深入探讨JavaCC的工作原理、CMM语法分析的关键步骤以及如何处理错误。 1. **JavaCC工作原理**: JavaCC基于LL(k)解析策略,允许用户定义文法规则,这些规则将被用来解析输入源代码。它会生成Java源代码...

    CMM语言解释器JAVA实现(javacc5.0)

    在实际的项目实现过程中,首先,开发者需要定义CMM语言的语法规则,这通常以一个JJT(JavaCC的抽象语法树)文件的形式完成。然后,使用javacc5.0工具处理这个JJT文件,生成对应的词法分析器和解析器的JAVA源代码。接...

    cmm程序语言编译器

    在编译过程中,CMM编译器会将高级语言(如C、C++或Java)的源代码转化为CMM代码,然后再将CMM代码转换为目标机器码,从而实现程序的执行。 编译器的前端部分主要负责源代码的解析和词法分析。它首先将源代码分解成...

    CMM语言解释器JAVA实现(javacc5.0)增强版

    这个增强版的实现是基于JAVA语言,并利用了javacc5.0工具来完成语法解析和词法分析的部分。下面将详细讨论相关知识点。 1. **CMM语言**:CMM可能代表一种特定的编程模型或领域专用语言(DSL),用于解决特定问题。...

    CMM词法分析器

    在编程语言解析领域,词法分析是编译器或解释器设计的重要组成部分。"CMM词法分析器"是一个特定的项目,旨在教授如何在Eclipse集成开发环境中使用javacc工具来构建词法分析器。这个词法分析器是针对一种名为"CMM"的...

    基于Java实现的CMM语言解释器,包括词法分析,语法分析等.zip

    `CMM语法分析设计.doc`可能包含了CMM语言的语法规则以及如何构建AST的详细信息。这一阶段的目标是确保输入的程序符合语言的语法规则。 3. **语义分析**:这一阶段检查程序的逻辑和上下文,例如类型检查、作用域解析...

    Java写的cmm词法分析器(源代码)及javacc学习心得文档

    Java编写的CMM词法分析器是用于解析特定语言(如CMM)源代码的工具,它是编译器或解释器的重要组成部分。词法分析器的任务是从源代码中识别出一个个有意义的单元,称为标记(Token),这些标记是语法分析阶段的输入...

    CMM.rar_CMM_cmm词法分析器_编译 词法分析 java

    "CMM_cmm词法分析器"指的是该压缩包内包含CMM语言的词法分析器源码,这可能是用Java编程语言实现的。Java是一种广泛使用的面向对象的编程语言,具有跨平台的特性,因此适合开发这样的工具。 描述中提到的"CMM语言...

    Javacc C--

    JavaCC 是一个强大的Java源代码生成器,主要用于构建解析器和词法分析器,尤其适用于处理复杂的语法结构。它是基于Java的,因此可以无缝地集成到Java应用程序中。在编译原理课程设计中,JavaCC是一个常用工具,可以...

    武汉大学国际软件学院解释器构造作业二——JAVACC 的研究和应用

    在解释器构造课程中,学生通常会学习如何设计和实现一个简单的语言解释器,这涉及到语法分析、语义分析以及代码执行等多个步骤。 JAVACC,全称为Java Compiler Compiler,是Java环境下的一种强大的词法分析器和语法...

    词法分析器

    描述中提到的“编译原理课程所做的javacc词法分析源代码”,意味着这是一个学习项目,可能包含了一组用JavaCC编写的源代码文件,用于实现特定编程语言的词法分析过程。"cmm词法分析器"可能是这个项目的名称,可能...

    解释器构造实践1

    在这个系列的实验中,我们将构建一个完整的CMM语言解释器,涵盖词法分析、语法分析、语义分析和代码执行的全过程。以下是每个实验的详细知识点: 实验1:CMM语言词法分析 词法分析是编译器的第一步,其目的是将源...

Global site tag (gtag.js) - Google Analytics