|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
最初被命名为Oak,目标设定在家用电器等小型系统的编程语言,来解决诸如电视机、电话、闹钟、烤面包机等家用电器的控制和通讯问题。条记
javaCC的功效和yacc类似,次要依据bnf范式天生剖析程序,不外javaCC是汇合了词法剖析和语法剖析天生java剖析代码,主页为:https://javacc.dev.java.net/
javaCC有三个工具
javaCC用来处置语法文件(jj)天生剖析代码;
jjTree用来处置jjt文件,天生树节点代码和jj文件,然后再经由过程javaCC天生剖析代码;
jjDoc依据jj文件天生bnf范式文档(html)
javaCC利用的各类言语的Grammar文件这里有良多http://www.cobase.cs.ucla.edu/pub/javacc/,比方html,xml,python,vb…..,良多充足用了,呵呵。
javaCC的利用
javaCC天生的文件中,最次要的是《Grammar》.java这个就是剖析器的主程序了了,《Grammar》名由jj中界说。
如今依据例子申明jj文件的界说:
BNF范式为:
Expression
::=
((<NEWLINE>)*Simple_Expression<NEWLINE>)*<EOF>
Simple_Expression
::=
Term(addopTerm)*
addop
::=
<PLUS>
|
<MINUS>
Term
::=
Factor(mulopFactor)*
mulop
::=
<TIMERS>
|
<OVER>
Factor
::=
<ID>
|
<NUM>
|
<MINUS>
|
<PLUS>
|
<LPAREN>Simple_Expression<RPAREN>
/*这是一个整数的四则运算的例子*/
/*运转javaCCGrammar.jj
javac*.java
javaGrammar
>>>1+1*(1+1)
3
>>>^Z
*/
PARSER_BEGIN(Grammar)/*剖析代码的出口*/
publicclassGrammar{
publicstaticfinalintPlusOP=1;
publicstaticfinalintMinusOP=2;
publicstaticfinalintTimersOP=3;
publicstaticfinalintOverOP=4;
publicstaticvoidmain(Stringargs[])throwsParseException{
Grammarparser=newGrammar(System.in);
parser.Expression();
}
}
PARSER_END(Grammar)
SKIP:/*不处置的字符*/
{
""|" "
}
TOKEN:/*天生token的字符界说*/
{
<ID:["a"-"z","A"-"Z","_"](["a"-"z","A"-"Z","_","0"-"9"])*>
|<NUM:(["0"-"9"])+>
|<PLUS:"+">
|<MINUS:"-">
|<TIMERS:"*">
|<OVER:"/">
|<LPAREN:"(">
|<RPAREN:")">
|<NEWLINE:("
"|"
"|"")>
}
voidExpression():
/*完成Expression::=((<NEWLINE>)*Simple_Expression<NEWLINE>)*<EOF>的配陪*/
{
intvalue=0;/*这个{}中是Expression()的界说的部分变量*/
}
{
{
System.out.print(">>>");
}
((<NEWLINE>/*起首婚配NEWLINE这个taken,完成后转到下一个剖析*/
{
System.out.print(">>>");/*在<NEWLINE>下的{}中为假如婚配到<NEWLINE>实行的java代码。*/
}
)*value=Simple_Expression()<NEWLINE>/*在换行之前Simple_Expression()剖析表达式,输出换行后,一个预算剖析完成*/
{System.out.println(value);
System.out.print(">>>");/*在<NEWLINE>下的{}中为完成表达式剖析,婚配到<NEWLINE>实行的java代码。*/
}
)*
<EOF>/*体系界说的taken,输出停止符*/
}
intSimple_Expression():
/*完成Simple_Expression::=bnfTerm(addopTerm)*配陪*/
{
/*这个{}中是Simple_Expression()的界说的部分变量*/
intvalue;
inttValue;
intop;
}
{
value=Term(){}/*配陪Term相*/
(
op=addop()tValue=Term()
{
switch(op)
{
casePlusOP:
value=value+tValue;
break;
caseMinusOP:
value=value-tValue;
break;
}
}
)*/*婚配(addopTerm)**/
{returnvalue;}
}
intaddop():{}
{
<PLUS>{returnPlusOP;}
|<MINUS>{returnMinusOP;}
}
intTerm():
{
intvalue;
inttValue;
intop;
}
{
value=Factor(){}
(
op=mulop()tValue=Factor()
{
switch(op)
{
caseTimersOP:
value=value*tValue;
break;
caseOverOP:
value=value/tValue;
break;
}
}
)*
{
returnvalue;
}
}
intmulop():{}
{
<TIMERS>{returnTimersOP;}
|<OVER>{returnOverOP;}
}
intFactor():
{
intvalue;
Tokent;
}
{
t=<ID>/*取得<ID>的剖析的值*/
{
value=100;
returnvalue;
}
|
t=<NUM>
{
value=(Integer.valueOf(t.image)).intValue();
returnvalue;
}
|
t=<MINUS>
{
value=0-Factor();
returnvalue;
}
|
t=<PLUS>
{
value=Factor();
returnvalue;
}
|
<LPAREN>value=Simple_Expression()<RPAREN>
{
returnvalue;
}
}
依据例子:基础上是一个taken下跟一个{}用于处置以后tabkn的java代码
jjTree的利用:
jjTree的利用,必要依据实践情形写本人的Node类,可是都必需完成Node.java接口,jjTree供应一个SimpleNode.java的复杂完成,也能够承继它,大概重写这个类。
给出一个javaCC本人带例子,也是四则运算:
语法界说:
Start
::=
Expression";"
Expression
::=
AdditiveExpression
AdditiveExpression
::=
(MultiplicativeExpression(("+"|"-")MultiplicativeExpression)*)
MultiplicativeExpression
::=
(UnaryExpression(("*"|"/"|"%")UnaryExpression)*)
UnaryExpression
::=
"("Expression")"
|
Identifier
|
Integer
Identifier
::=
<IDENTIFIER>
Integer
::=
<INTEGER_LITERAL>
options{
MULTI=true;
VISITOR=true;/*完成婚配的visitor形式代码*/
NODE_DEFAULT_VOID=true;/*剖析函数默许不天生node类*/
}
/*jtt默许的天生node类名,都带AST前缀加受骗前剖析的语意的称号*/
PARSER_BEGIN(eg4)
classeg4{
publicstaticvoidmain(Stringargs[]){
System.out.println("Readingfromstandardinput...");
eg4t=neweg4(System.in);
try{
ASTStartn=t.Start();
eg4Visitorv=neweg4DumpVisitor();
n.jjtAccept(v,null);
System.out.println("Thankyou.");
}catch(Exceptione){
System.out.println("Oops.");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
PARSER_END(eg4)
SKIP:
{
""
|" "
|"
"
|""
|<"//"(~["
",""])*("
"|""|"
")>
|<"/*"(~["*"])*"*"(~["/"](~["*"])*"*")*"/">
}
TOKEN:/*LITERALS*/
{
<INTEGER_LITERAL:
<DECIMAL_LITERAL>(["l","L"])?
|<HEX_LITERAL>(["l","L"])?
|<OCTAL_LITERAL>(["l","L"])?
>
|
<#DECIMAL_LITERAL:["1"-"9"](["0"-"9"])*>
|
<#HEX_LITERAL:"0"["x","X"](["0"-"9","a"-"f","A"-"F"])+>
|
<#OCTAL_LITERAL:"0"(["0"-"7"])*>
}
TOKEN:/*IDENTIFIERS*/
{
<IDENTIFIER:<LETTER>(<LETTER>|<DIGIT>)*>
|
<#LETTER:["_","a"-"z","A"-"Z"]>
|
<#DIGIT:["0"-"9"]>
}
ASTStartStart()#Start:{}/*#Start天生界说的节点类,称号为前缀+Start.Java*/
{
Expression()";"
{returnjjtThis;}
}
voidExpression():{}
{
AdditiveExpression()
}
voidAdditiveExpression():{}
{
(
MultiplicativeExpression()(("+"|"-")MultiplicativeExpression())*
)#Add(>1)/*Add#当满意前提(>1),Add天生界说的节点类,称号为前缀+Add.Java*/
}
voidMultiplicativeExpression():{}
{
(
UnaryExpression()(("*"|"/"|"%")UnaryExpression())*
)#Mult(>1)/*#Mult当满意前提(>1),Mult天生界说的节点类,称号为前缀+Mult.Java*/
}
voidUnaryExpression():{}
{
"("Expression()")"|Identifier()|Integer()
}
voidIdentifier()#MyOtherID:/*#MyOtherID天生界说的节点类,称号为前缀+MyOtherID.Java*/
{
Tokent;
}
{
t=<IDENTIFIER>
{
jjtThis.setName(t.image);
}
}
voidInteger()#Integer:{}/*#Integer天生界说的节点类,称号为前缀+Integer.Java*/
{
<INTEGER_LITERAL>
}
jjDoc的利用很复杂。
假如必要天生别的言语的(比方C#)剖析器,除处置C的yacc和lex外,ANTLR(http://www.antlr.org/)也是一个不错的选择。
你对java乐观有点盲目。java的关键就是在服务器上表现优异,而且它提供了整个开发所需要的工具。应该是说,看哪天。net有没有机会赶上java。 |
|