這裏說的是javacc的.jj文件
基本構成
語法分析器的屬性設置
- options內的即爲需要設置的一些屬性,但是一些基本不需要設置,詳細設置可以百度,新手一般用不上,一般情況下,寫如下配置即可
options { static = false; //語法分析器是否爲靜態 }
語法分析器的類聲明
-
這裏是生成java函數入口,從PARSER_BEGIN(xxx)開始,到PARSER_END(xxx)結束,這裏的xxx需要和最終生成的java的類名相同
PARSER_BEGIN(Adder) public class Adder{ public static void main(String[] args) throws ParseException, TokenMgrError{ Adder adder= new Adder(System.in); System.out.println(adder.start()); } } PARSER_END(Adder)
詞法跳過聲明
-
SKIP是需要添加一些跳過的字符,一般情況下,跳過空格,Tab,換行,回車及格,相互之前,用“|”分割,
這裏的跳過註釋,使用的是jacc的語法,和正則表達式相似//跳過字符 SKIP : { " " //跳過空格 | "\t" //跳過Tab | "\n" //跳過換行 | "\r" //跳過回車 | <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")> //跳過單行註釋 | <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> //跳過多行註釋 }
詞法定義關鍵字
- TOKEN可以定義一些需要識別的關鍵字,其中以#號開頭的token只是在詞法分析時使用,而不能做法語法分析的輸入,也就是說。它相對詞法分析是局部的,內部的
TOKEN:/* 定義整數 */ { <INTEGER_LITERAL:["1"-"9"](<DIGIT>)*> } TOKEN:/* 定義實數 */ { <REAL_LITERAL:(<DIGIT>)+ | (<DIGIT>)+"." | (<DIGIT>)+"."(<DIGIT>)+ | "."(<DIGIT>)+> } TOKEN:/*定義數字*/ { <#DIGIT:["0"-"9"]> }
語法規則實現
- 第一行是聲明返回值和函數名,然後的{TOKEN ···}是聲明函數中用到的變量名,最後的{···}中是函數的邏輯實現,其中第一行是匹配輸入的語句,這裏匹配的語句是 "a+b+c"的類型的,如果不是這個類型,那麼會報錯
long expr(): { Token x, y, z; } { x=<INTEGER> "+" y=<INTEGER> "+" z=<INTEGER><EOF> { return Long.parseLong(x.image) + Long.parseLong(y.image) + Long.parseLong(z.image); } }
完整例子
/**
* JavaCC template file created by SF JavaCC plugin 1.5.28+ wizard for JavaCC 1.5.0+
*/
options
{
static = true;
}
PARSER_BEGIN(testJavacc)
package javaccJJT;
public class testJavacc
{
public static void main(String args []) throws ParseException
{
testJavacc parser = new testJavacc(System.in);
while (true)
{
System.out.println("Reading from standard input...");
System.out.print("Enter an expression like \"1+(2+3)*4;\" :");
try
{
switch (testJavacc.one_line())
{
case 0 :
System.out.println("OK.");
break;
case 1 :
System.out.println("Goodbye.");
break;
default :
break;
}
}
catch (Exception e)
{
System.out.println("NOK.");
System.out.println(e.getMessage());
testJavacc.ReInit(System.in);
}
catch (Error e)
{
System.out.println("Oops.");
System.out.println(e.getMessage());
break;
}
}
}
}
PARSER_END(testJavacc)
SKIP :
{
" "
| "\r"
| "\t"
| "\n"
}
TOKEN : /* OPERATORS */
{
< PLUS : "+" >
| < MINUS : "-" >
| < MULTIPLY : "*" >
| < DIVIDE : "/" >
}
TOKEN :
{
< CONSTANT : (< DIGIT >)+ >
| < #DIGIT : [ "0"-"9" ] >
}
int one_line() :
{}
{
sum() ";"
{
return 0;
}
| ";"
{
return 1;
}
}
void sum() :
{}
{
term()
(
(
< PLUS >
| < MINUS >
)
term()
)*
}
void term() :
{}
{
unary()
(
(
< MULTIPLY >
| < DIVIDE >
)
unary()
)*
}
void unary() :
{}
{
< MINUS > element()
| element()
}
void element() :
{}
{
< CONSTANT >
| "(" sum() ")"
}