javacc实践
背景
JavaCC是Java的解析器生成器兼扫描器生成器。为JavaCC描述好语法的规则,JavaCC就能够生成可以解析该语法的扫描器和解析器。JavaCC是LL解析器生成器,因此比起LR解析器生成器和LALR解析器生成器,它有着可处理语法的范围相对狭哉的缺点。但是,JavaCC生成的解析器有易于理解,易于使用的优势。且支持无限长的token超前扫描特性,所以速度非常的快。
特征
JavaCC™是一种用Java编程语言编写的Java解析器生成器。它生成纯Java代码。JavaCC和JavaCC生成的解析器都已在各种Java平台上运行。JavaCC附带了许多语法,包括Java 1.0.2,Java 1.1和Java 2以及一些HTML语法。
要点总结
e1 | e2 | e3 | 条件选项
( e )+ 1次以上
( e )* 多次以上
( … )? : 可选匹配
[“a”-“z”] 小写字母
~[] 匹配任何字符
~["\n","\r"] 匹配任何新行字符
因公司一个项目(MOCK挡板平台)用到此技术,由此对此技术进行学习和研究,了解到此技术的使用,总结了以下应用场景。 应用场景:
- 文本内容匹配和计算处理。如四则运算、特定字母匹配和计算。
- 基于1的自定义逻辑规则(if else for)、自定义method实现特定场景。实现文本中控制逻辑和调用方法的目的。-应用场景。基于java agent技术对接口和方法进行控制。实现mock 接口和代码进行分离。
例子1-两数相加:
options {
STATIC = false;
}
PARSER_BEGIN(Person)
import java.io.*;
class Person {
static public void main (String[] args) {
for (String arg : args) {
try {
System.out.println(evaluate(arg));
}
catch (ParseException ex) {
System.err.println(ex.getMessage);
}
}
}
static public long evaluate (String src) throws ParseException {
Reader reader = new StringReader(src);
return new Person(reader).expr();
}
}
PARSER_END(Person)
SKIP: { < [" ","\t","\r","\n"] > }
TOKEN: {
<INTEGER: (["0"-"9"])+>
}
long expr():
{
Token x,y;
}
{
x=<INTEGER> "+" y=<INTEGER> <EOF>
{
return Long.parseLong(x.image) + Long.parseLong(y.image);
}
}
执行
java Person 1+1
或者
ecplise /idea输入程序参数即可。
输出3
例子2-括号匹配
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 :
{
" "
| "\t"
| "\n"
| "\r"
}
/** Root production. */
void Input() :
{}
{
MatchedBraces() <EOF>
}
/** Brace matching production. */
void MatchedBraces() :
{}
{
"{" [ MatchedBraces() ] "}"
}
运行Simple2
java Simple2
{{ } }
无报错,输入其他字符报错。
例子3-字符统计
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: ["a"-"z","A"-"Z","_"] ( ["a"-"z","A"-"Z","_","0"-"9"] )* >
|
< NUM: ( ["0"-"9"] )+ >
}
/** Top level production. */
void ExpressionList() :
{
String s;
}
{
{
System.out.println("Please type in an expression followed by a \";\" or ^D to quit:");
System.out.println("");
}
( s=Expression() ";"
{
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() :
{
java.util.Vector termimage = new java.util.Vector();
String s;
}
{
s=Term()
{
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()
{
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;
}
}
}
/** A Factor. */
String Factor() :
{
Token t;
String s;
}
{
t=<ID>
{
return t.image;
}
|
t=<NUM>
{
return t.image;
}
|
"(" s=Expression() ")"
{
return s;
}
}
输入:
Please type in an expression followed by a “;” or ^D to quit:
aes+123agd123abd+ssseeee;
the sum of aes, the product of 123, agd, 123, and abd, and the product of sss and eeee