what is JavaCC ?

今天接触到了javacc!

1,官方网站https://javacc.dev.java.net/ 

2,使用javacc处理格式化文本

什么是javacc,他该怎么用麻烦您请教一下google吧,有详细解答。
接着解释什么是终结符。终结符就是一个正则表达式,他是一个什么样的形式差不多已经确定了。比如我要定义一个冒号,就可以这么写< COLON : “:”>, 要是定义一个整数我可以这么写 < INTEGER: ([”0″-”9″])+>,  []表示这里面的东西任选一个,”0″-”9″是一个缩写,你也可以写成类似[”0″|”1″|”2″|”3″] 为了用那个加号,要先用括号扩起来,后面那个加号表示方括号里面内容可以出现一次或者多次比如0,02,3482什么的都可以了。
接着讲非终结符 把终结符串串就成了非终结符。玩把深沉,给个递归的定义:非终结符=终结符+非终结符 ,当然写成非终结符=非终结符+终结符。不过这两种不是完全等价的,有兴趣的可以参考龙书。
 
干说说不清,举个例子。假设我现在有这么一个存储电话号码的文本文件。
 
tom:home 12345
    office 23456
peter: office 34567
alice:home 45678
 
 
语法很简单了,两个关键字,分别是home和office表示家里或者办公室电话,要是没有就可以不写,姓名和电话条目后面用分号格开。
首先我们把这整个文件看成是一个大的非终结符,就叫他parser吧。我们看下parse的推导过程:(约定小写的是非终结符,大写的是终结符)
parser--> (people_item)*   //这里用*表示可以出现一次或者多次,因为文件可以空的啊
 
people_item --> STRING COLON (number_item)*
 
number_item–> OFFICE INTEGER
              |HOME_INTEGER
 
以上就解析例子文本的文法推导过程,推导说白了就是把一个巨复杂的非终结符演算成全是终结符,而且没有歧义
 
对照着以上的推导过程我们给出javacc看的懂的jj文件,说明都放到注释里了
 
options
{
  DEBUG_PARSER=true; //加上这个系统参数是为了可以显示文法推导的过程
}
PARSER_BEGIN(TelParser) //TelParser就是你最想要得那个东西,你也可以叫其他名字
public class TelParser  //这块和写普通的java类比较像,不过javacc会自动加进来一些方法用来解析非终结符
{
    public static void main(String args[])
    {
        TelParser parser;
        if (args.length == 1)
        {
            System.out.println(”Reading from file ” + args[0] + ” . . .”);
            try
            {
                parser = new TelParser(new java.io.FileInputStream(args[0]));
                //下面这句就是文法分析的入口啊,表示整个文件的非终结符
                //parser()是半自动生成的,以为后文你对他进行了说明
                parser.parser();
                System.out.println(”ok”);
            }catch (Exception e)
                   {
                        e.printStackTrace();
                        return;
                   }
        }
     
    }
}
PARSER_END(TelParser)
 
//要忽略的东西都放到SKIP里来
/* WHITE SPACE */
SKIP :
{
  ” ”
| “/t”
| “/n”
| “/r”
| “/f”
| “/r/n”
}
 
//TOKEN是定义终结符的,不多说了,看看就懂了把
/* SEPARATORS */
TOKEN :
{
 
    < COLON : “:”>
  | < EQU:   “=” >
  | < LBRACE: “{” >
  | < RBRACE: “}” >
  | < SEMICOLON: “;” >
  | < COMMA: “,” >
}
/* RESERVED WORDS*/
TOKEN :
{
    <HOME : “home”>
   |<OFFICE : “office”>
}
/*LITERALS*/
TOKEN :
{
    < INTEGER: ([”0″-”9″])+>
  | < STRING : ([”A”-”Z”, “a”-”z”, “0″-”9″])+ > 
}
//入口非终结符
void parser()://冒号不要丢啊
{
   //语法分析阶段可以放一些变量申明
}
{
    (peopleItem())* //看推导开始了
}
void peopleItem():
{
}
{
    <STRING><COLON>(numberItem())*
}
void numberItem():
{
}
{
    [<OFFICE>|<HOME>] <INTEGER>
  
}
 
以上就是文法分析的过程
但是也许你会问,按照上面的文法,我给一个人写两遍office电话也是合法的。是的,是有这个问题。这个问题需要在语法分析阶段解决了。下回再说

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值