美文网首页编译原理
JavaCC 学习笔记

JavaCC 学习笔记

作者: 走在成长的道路上 | 来源:发表于2020-02-14 22:52 被阅读0次

最近尝试使用 corenlp 做数据抽取工作,发现其中使用 JavaCC 进行文本操作。

JavaCC 是一个词法分析生成器和语法分析生成器。词法分析和语法分析是处理输入字符序列的软件组件,编译器和解释器协同词法分析和语法分析来解码程序文件。词法分析器可以把一连串的字符序列划分成一个一个的叫做 Token 的子序列,同时它也可以把这些 Token 分类。这些 Token 序列将会传送给语法分析器以供其决定程序的结构。

JavaCC 的输入文件是一个词法和语法的规范文件,其中也包括一些动作的描述,它的后缀应该是 *.jj

先来个基础样例:

//**
 * 设定选项参数
 */
//options {
//    LOOKAHEAD = 1;          // 预读 token 数量
//    STATIC = false;         // 是否生成静态函数
//    UNICODE_INPUT = true;   // 是否使用 Unicode 输入
//    DEBUG_PARSER = false;   // 是否输出调试信息
//}

/**
 * 定义解析类, 由
 * PARSER_BEGIN (类名)
 *  ...正文...
 * PARSER_END (类名)
 * 来构成主类之间的主函数 main 实现
 */
PARSER_BEGIN (Calc)
package calc;

import java.io.*;

/**
 * Macro statements are as follows :
 *   <List> ::= { <E> "=" }
 *   <E> ::= <T> { ( "+" <T> ) | ( "-" <T> ) } 
 *   <T> ::= <F> { ( "*" <F> ) | ( "/" <F> ) | ( "%" <F> ) } 
 *   <F> ::= ( "(" <E> ")" ) | INTEGER
 * Execute as follows :
 * $ javac Calc.java
 * $ java Calc [inputfile]
 */
public class Calc {
    public static void main (String args[]) {
        Calc parser;
        try {
            if (args.length == 0) {
                parser = new Calc (System.in);
            } else {
                parser = new Calc (new FileReader (args[0]));
            }
            parser.enable_tracing();
            parser.List();
        } catch (Exception err_mes) {
            System.err.println (err_mes);
        }
    }
}
PARSER_END (Calc)

/**
 * 定义空白字符及字符串
 * 空白字符以
 * SKIP :
 * {
 *     <模板>
 * }
 * 的形式进行定义,模板内容可为正则表达式。
 */
SKIP :
{
    < " " | "\t" | "\n" | "\r" >
}

/**
 *  定义 token 类型
 *  Token 的形式如下:
 * TOKEN :
 * {
 *     <Token 名称/类型: 模板>
 * }
 * 的形式进行定义,模板内容可为正则表达式。
 */
TOKEN : {
    <INTEGER: (["0"-"9"])+>
}

/**
 * 实现执行赋值表达式
 * <List> ::= { <E> "=" }
 * void parseList() {
 *     int value;
 *     while (true) {
 *         value = parseE();
 *         if (token == "=")
 *             System.out.println (value);
 *     }
 * }
 */
void List() :
{ int value; }
{
    (
        value = E()
        "=" { System.out.println (value); }
    )*
}

/**
 * 实现基础运算表达式
 * <E> ::= <T> { ( "+" <T> ) | ( "-" <T> ) } 
 * void parseE() {
 *     int result1, result2;
 *     result1 = parseT();
 *     while (token == "+" || token == "-") {
 *         if (token == "+") {
 *             result2 = parseT();
 *             result1 += result2;
 *         } else if (token == "-") {
 *             result2 = parseT();
 *             result1 -= result2;
 *     }
 *     return result1;
 * }
 */
int E() :
{ int result1, result2; }
{
    result1 = T()
    (
        "+" result2 = T() { result1 += result2; }
      | "-" result2 = T() { result1 -= result2; }
    )*
    { return result1; }
}

/**
 * 实现 乘 除 余 运算表达式
 * <T> ::= <F> { ( "*" <F> ) | ( "/" <F> ) | ( "%" <F> )} 
 * void parseT() {
 *     int result1, result2;
 *     result1 = parseF();
 *     while (token == "*" || token == "/" || token == "%") {
 *         if (token == "*") {
 *             result2 = parseF();
 *             result1 *= result2;
 *         } else if (token == "/") {
 *             result2 = parseF();
 *             result1 /= result2;
 *         } else if (token == "%") {
 *             result2 = parseF();
 *             result1 %= result2;
 *     }
 *     return result1;
 * }
 */
int T() :
{ int result1, result2; }
{
    result1 = F()
    (
        "*" result2 = F() { result1 *= result2; }
      | "/" result2 = F() { result1 /= result2; }
      | "%" result2 = F() { result1 %= result2; }
    )*
    { return result1; }
}

/**
 * 实现 括号 运算表达式
 * <F> ::= ( "(" <E> ")" ) | INTEGER
 * void parseF() {
 *     int result;
 *     if (token == "(") {
 *         nextToken();
 *         result = parseE();
 *         if (token == ")") nextToken();
 *         return result;
 *     } else if (token == INTEGER) {
 *         return token.getValue();
 *     }
 * }
 */
int F():
{ int result; }
{
    "(" result = E() ")" { return result; }
    | token = <INTEGER> { return Integer.parseInt (token.image); }
}

参考

相关文章

网友评论

    本文标题:JavaCC 学习笔记

    本文链接:https://www.haomeiwen.com/subject/zonjfhtx.html