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