`

javacc学习概述

 
阅读更多

JavaCC(Java Compiler Compiler)是一个用JAVA开发的最受欢迎的语法分析生成器。这个分析生成器工具可以读取上下文无关且有着特殊意义的语法并把它转换成可以识别且匹配该语法的JAVA程序。JavaCC可以在Java虚拟机(JVM) V1.2或更高的版本上使用,它是100%的纯Java代码,可以在多种平台上运行,与Sun当时推出Java的口号"Write Once Run Anywhere"相一致。JavaCC还提供JJTree工具来帮助我们建立语法树,JJDoc工具为我们的源文件生成BNF范式(巴科斯-诺尔范式)文档(Html);

       我们下载了javacc的开发包,只要把里面的例子全部读懂就可以深入了解javacc的语法过程;现在来看第一个例子

options {
  LOOKAHEAD = 1;
  CHOICE_AMBIGUITY_CHECK = 2;
  OTHER_AMBIGUITY_CHECK = 1;
  STATIC = true;
  DEBUG_PARSER = false;
  DEBUG_LOOKAHEAD = false;
  DEBUG_TOKEN_MANAGER = false;
  ERROR_REPORTING = true;
  JAVA_UNICODE_ESCAPE = false;
  UNICODE_INPUT = false;
  IGNORE_CASE = false;
  USER_TOKEN_MANAGER = false;
  USER_CHAR_STREAM = false;
  BUILD_PARSER = true;
  BUILD_TOKEN_MANAGER = true;
  SANITY_CHECK = true;
  FORCE_LA_CHECK = false;
}

PARSER_BEGIN(Simple1)

/** Simple brace matcher. */
public class Simple1 {

  /** Main entry point. */
  public static void main(String args[]) throws ParseException {
//这里system.in使用的是键盘输入
    Simple1 parser = new Simple1(System.in);
    parser.Input();
  }

}

PARSER_END(Simple1)

/** Root production. */
void Input() :
{}
{//("\n"|"\r")* 表示若干个换行<EOF>为最后终止符号
  MatchedBraces() ("\n"|"\r")* <EOF>
}

/** 这里是包含匹配的,如果熟悉正则表达式就很容易了解,这里MatchedBraces匹配的是多个{}*/
void MatchedBraces() :
{}
{
  "{" [ MatchedBraces() ] "}"
}

 我们看到这个是个simple1.jj的简单例子,这个javacc是由jj或者jjt描述文件组成的,他一般分为option部分,主体部分就是class定义的相当一个java的类,还有就是token部分,上面的函数主要是匹配数个{}

如:"{}", "{{{{{}}}}}"

 第二个例子simple2.jj

PARSER_BEGIN(Simple2)

/** Simple brace matcher. */
public class Simple2 {

  /** Main entry point. */
  public static void main(String args[]) throws ParseException {
    Simple2 parser = new Simple2(System.in);
    parser.Input();
  }

}

PARSER_END(Simple2)
//skip属于系统的关键字表示将会忽略里面描述的字符
SKIP :
{
//忽略空格和换行符号
  " "
| "\t"
| "\n"
| "\r"
}

/** Root production. */
void Input() :
{}
{//EOF是个固有文本流输入终止符号
  MatchedBraces() <EOF>
}

/** Brace matching production. */
void MatchedBraces() :
{}
{
  "{" [ MatchedBraces() ] "}"
}

 这个例子也是匹配若干个{} 但是跟第一个例子不同的是,它可以匹配输入的的{和}之间有换行或者空格

 

第三个例子simple3.jj

PARSER_BEGIN(Simple3)

/** Simple brace matcher. */
public class Simple3 {

  /** Main entry point. */
  public static void main(String args[]) throws ParseException {
    Simple3 parser = new Simple3(System.in);
    parser.Input();
  }

}

PARSER_END(Simple3)

SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
}
//TOKEN是一个系统关键词,它是用户可以自定义自己的描述,并且由系统识别然后传递用户处理
TOKEN :
{//如我们定义一个LBRACE 是{字符 定义一个token形式是<字符变量:用户定义的字符串或常量>
  <LBRACE: "{">
| <RBRACE: "}">
}

/** Root production. */
void Input() :
//放在这行表示自定义变量count
{ int count; }
{
//count存放的是MatchedBraces函数返回的数值,并在java代码片段打印出来
  count=MatchedBraces() <EOF>
//后面跟的是java代码片段,用户可以自己定义
  { System.out.println("The levels of nesting is " + count); }
}

/** Brace counting production. */
int MatchedBraces() :
//nested_count定义变量
{ int nested_count=0; }
{
//这里匹配{}*然后nested_count递增 作用是算出输入文本流含有多少个{}串
  <LBRACE> [ nested_count=MatchedBraces() ] <RBRACE>
//插入java代码片段
  { return ++nested_count; }
}

 simple3.jj计算出的是一个输入文本流含有多少个{}串

 

第四个例子:

PARSER_BEGIN(IdList)


/** ID lister. */
public class IdList {

  /** Main entry point. */
  public static void main(String args[]) throws ParseException {
    IdList parser = new IdList(System.in);
    parser.Input();
  }

}

PARSER_END(IdList)
//忽略空格和换行符号
SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
}
//定义一个id为字符开头,后面带着字符串或者数字组成的TOKEN字符串
TOKEN :
{
  < Id: ["a"-"z","A"-"Z"] ( ["a"-"z","A"-"Z","0"-"9"] )* >
}

/** Top level production. */
void Input() :
{}
{//匹配输入多个字符串并且以EOF结束
  ( <Id> )+ <EOF>
}

 第五个例子

PARSER_BEGIN(NL_Xlator)

/** New line translator. */
public class NL_Xlator {

  /** Main entry point. */
  public static void main(String args[]) throws ParseException {
    NL_Xlator parser = new NL_Xlator(System.in);
    parser.ExpressionList();
  }

}

PARSER_END(NL_Xlator)

SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
}

TOKEN :
{
//ID为字母和数字组成的字符串
  < ID: ["a"-"z","A"-"Z","_"] ( ["a"-"z","A"-"Z","_","0"-"9"] )* >
|
//NUM为数字串
  < NUM: ( ["0"-"9"] )+ >
}

/** Top level production. */
void ExpressionList() :
{//定义一个字符串s
	String s;
}
{
//这里插入一个java代码段,打印输出字符串
	{
	  System.out.println("Please type in an expression followed by a \";\" or ^D to quit:");
	  System.out.println("");
	}
//开始匹配一段表达式以";"作为结尾
  ( s=Expression() ";"
	{//插入java代码段
	  System.out.println(s);
	  System.out.println("");
	  System.out.println("Please type in another expression followed by a \";\" or ^D to quit:");
	  System.out.println("");
	}
  )*
  <EOF>
}

/** An Expression. */
String Expression() :
{//定义vector和s变量
	java.util.Vector termimage = new java.util.Vector();
	String s;
}
{
  s=Term()
	{//java代码段
	  termimage.addElement(s);
	}
  ( "+" s=Term()
	{
	  termimage.addElement(s);
	}
  )*
	{
	  if (termimage.size() == 1) {
	    return (String)termimage.elementAt(0);
          } else {
            s = "the sum of " + (String)termimage.elementAt(0);
	    for (int i = 1; i < termimage.size()-1; i++) {
	      s += ", " + (String)termimage.elementAt(i);
	    }
	    if (termimage.size() > 2) {
	      s += ",";
	    }
	    s += " and " + (String)termimage.elementAt(termimage.size()-1);
            return s;
          }
	}
}

/** A Term. */
String Term() :
{
	java.util.Vector factorimage = new java.util.Vector();
	String s;
}
{
//s获取到Factor的token返回的内容,并使用factorimage存放
  s=Factor()
	{
	  factorimage.addElement(s);
	}
  ( "*" s=Factor()
	{
	  factorimage.addElement(s);
	}
  )*
	{
	  if (factorimage.size() == 1) {
	    return (String)factorimage.elementAt(0);
          } else {
            s = "the product of " + (String)factorimage.elementAt(0);
	    for (int i = 1; i < factorimage.size()-1; i++) {
	      s += ", " + (String)factorimage.elementAt(i);
	    }
	    if (factorimage.size() > 2) {
	      s += ",";
	    }
	    s += " and " + (String)factorimage.elementAt(factorimage.size()-1);
            return s;
          }
	}
}

/** Factor作用是返回TOKEN的变量内容 */
String Factor() :
{
	Token t;
	String s;
}
{
  t=<ID>
	{
//t.image表示获取到t的内容,假如t匹配<ID>的字符串是“ABCD” 则t.image内容是“ABCD”
	  return t.image;
	}
|
  t=<NUM>
	{
	  return t.image;
	}
|
  "(" s=Expression() ")"
	{
	  return s;
	}
}

 

分享到:
评论

相关推荐

    JavaCC学习与应用

    ### JavaCC 学习与应用知识点详解 #### 一、JavaCC 概述 - **定义**:JavaCC(Java Compiler Compiler)是一款用于Java开发的语法分析生成器工具,能够根据给定的文法文件自动生成Java代码,这些Java代码能够解析...

    用JavaCC构造编译器的方法

    JavaCC概述 JavaCC是Sun公司开发的一款强大的编译器自动生成工具,它可以用于生成Java语言的词法分析器和语法分析器。相比于传统的编译器生成工具如YACC等,JavaCC具有以下几个优势: 1. **文法规则表达能力强**...

    javacc中文开发案例

    ### JavaCC中文开发案例 #### 简介与概述 JavaCC是一款强大的工具,用于构建编译器或解析...无论是对于想要深入了解编译器工作原理的学习者,还是希望创建自己专属语言的开发者来说,JavaCC都是一个不可或缺的工具。

    lucene学习全方面剖析总结

    #### Lucene 原理与应用概述 Lucene 是一个高性能、全文检索的开源库,被广泛应用于各种搜索引擎的开发之中。本篇文章旨在全面剖析 Lucene 的核心技术和应用场景,帮助读者深入理解 Lucene 的工作原理,并能够运用...

    编译原理实习

    - **实验背景**:此实验旨在帮助在校学生加深对编译原理的理解,特别是针对那些在学习编译原理课程时遇到困难的学生。该实验手册由西北农林科技大学信息工程学院于2010年9月29日发布,提供了关于词法分析、语法分析...

    java实现的语法分析器及词法分析器.zip

    "README.md" 文件是项目说明文档,通常包含项目概述、如何运行、依赖项和其他相关指南。在这个案例中,它可能解释了如何构建和测试词法分析器和语法分析器,以及可能的示例输入和预期输出。 "src" 目录通常包含源...

    UCLA编译技术课件

    - **第5章:JavaCC和JTB** - 学习使用这些工具进行语法分析和抽象语法树的构建。 - **第6章:语义分析** - 涉及类型检查、符号表管理等内容。 - **第7章:翻译与简化** - 如何将高级语言表达式转换为更简单的形式。 ...

    南开大学编译原理教程(PPT)

    1. **编译器概述**:编译器是连接高级语言和机器语言的桥梁,它的主要任务是将源代码(高级语言)翻译成目标代码(机器语言)。这个过程包括词法分析、语法分析、语义分析和优化等多个步骤。 2. **词法分析**:...

    MiniJava编译器

    1. **编译器概述**:编译器是计算机科学中的一个重要组成部分,它将源代码(一种高级编程语言)转换为目标代码(机器语言或字节码),使得计算机能够执行程序。MiniJava编译器专注于MiniJava语言,这是一种简化版的...

    又是一个语法分析的的小程序

    综上所述,本文档提供了一个关于编译原理课程中语法分析部分项目的概述。通过使用不同的解析器生成工具和技术,学生可以深入理解语法分析的过程,并实际操作编写相应的解析器代码。这对于学习编译原理的基础概念及其...

    JGeekCode:极客代码的 Java 实现

    【标题】"JGeekCode:极客代码的 Java 实现"揭示了这是一个与Java编程相关的项目,专注于实现特定的代码或...以上是对JGeekCode项目可能涵盖的知识点的详细概述,具体的学习内容将取决于项目的实际实现和提供的示例。

    SmartCalculator

    Java中,可以使用正则表达式来识别数字和运算符,然后通过递归下降解析(Recursive Descent Parsing)或者使用现成的解析库(如JavaCC或ANTLR)来构建抽象语法树(AST,Abstract Syntax Tree)。在这个树结构中,每...

    KAJ查询引擎

    在深入理解其技术细节之前,我们先来概述一下查询引擎的基本概念。查询引擎是信息检索系统的核心部分,它接收用户的查询,解析查询语句,然后在数据源中寻找相关信息,最后返回最相关的结果。在Java环境下,开发这样...

Global site tag (gtag.js) - Google Analytics