zoukankan      html  css  js  c++  java
  • 3.JavaCC 语法描述文件的格式解析

      JavaCC的语法描述文件格式如下所示:

    options {
        JavaCC的选项
    }
    
    PARSER_BEGIN(解析器类名)
    package 包名;
    import 库名;
    
    public class 解析器类名 {
        任意的Java代码
    }
    PARSER_END(解析器类名)
    
    扫描器的描述
    
    解析器的描述
    

      JavaCC和java一样将解析器的内容 定义在单个类中 ,因此会在PARSER_BEGIN和PARSER_END之间描述这个类的相关内容。

    下面拿一段实际代码来做示例,并对代码进行逐段拆分解析。

    1. 示例代码

    options {
        STATIC = false;
    }
    
    PARSER_BEGIN(Adder)
    package com.susu.testJavaCC;
    import java.io.*;
    public class Adder {
        public static void main(String[] args) {
            for (String arg : args) {
                try {
                    System.out.println(evaluate(arg));
    //                return(evaluate(arg));
                } catch (ParseException ex) {
                    System.err.println(ex.getMessage());
                }
            }
        }
    
        public static long evaluate(String src) throws ParseException {
            Reader reader = new StringReader(src);
            return new Adder(reader).expr();
        }
    }
    PARSER_END(Adder)
    
    SKIP: { <[" ", "	", "
    ", "
    "]> }
    TOKEN: {
        <INTEGER: (["0"-"9"])+>
    }
    
    long expr():
    {
        Token x, y;
    }
    {
        x=<INTEGER> "+" y=<INTEGER> <EOF>
        {
            return Long.parseLong(x.image) + Long.parseLong(y.image);
        }
    }
    

    2. 代码结构解析

    1. options块中将STATIC选项设置为false, 将该选项设置为true的话JavaCC生成的所有成员及方法都将被定义为static,若将STATIC设置为true则所生成的解析器无法在多线程环境下使用,因此该选项总是被设置为false。(STATIC的默认值为true)
    2. 从PARSER_BEING(Adder)到PARSER_END(Adder)是解析器类的定义。解析器类中需要定义的成员和方法也写在这里。为了实现即使只有Adder类也能够运行,这里定义了main函数。
    3. 之后的SKIP和TOKEN部分定义了扫描器。SKIP表示要跳过空格、制表符(tab)和换行符。TOKEN表示扫描整数字符并生成token。
    4. long expr...开始到最后的部分定义了狭义的解析器。这部分解析token序列并执行某些操作。

    3. main函数代码解析

      main函数将所有命令行参数的字符串作为计算对象的算式,依次用evaluate方法进行计算。
      evaluate方法中生成了Adder类的对象实例 。并让Adder对象来计算(解析)参数字符串src。
      要运行JavaCC生成的解析器类,需要下面2个步骤:

    1. 生成解析器类的对象实例
    2. 用生成的对象调用和需要解析的语句同名的方法

    第1点: JavaCC4.0和JavaCC5.0生成的解析器中默认定义有如下四种类型的构造函数。

    • Parser(InputStream s):第1种的构造函数是通过传入InputStream对象来构造解析的。这个构造函数无法设定输入字符串的编码,因此无法处理中文字符等。
    • Parser (InputStream s, String encoding):第2种的构造函数除了InputStream对象外,还可以设置输入字符串的编码来生成解析器。但如果要解析中文字符串或注释的话,就必须使用第2种/3种构造函数。
    • Parser(Reader r):第3种的构造函数用于解析Reader对象所读入的内容。
    • Parser (x x x x TokenManager tm):第4种是将扫描器作为参数传入。

      解析器生成后,用这个实例调用和需要解析的语法同名的方法。这里调用Adder对象的expr方法,接回开始解析,解析正常结束后会返回语义值。

  • 相关阅读:
    python操作excel表格
    重学Java
    重学Java
    重学Java
    重学Java
    重学Java
    博客园自定义主题及目录组件
    重学Java
    修改 Eclipse 背景颜色的高级方法
    dbf转excel
  • 原文地址:https://www.cnblogs.com/suhaha/p/11697970.html
Copyright © 2011-2022 走看看