这篇文章主要介绍“Java LPAREN怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java LPAREN怎么用”文章能帮助大家解决问题。
为了让词法分析做得更简单,我们通常都不会在文法分析的时候,使用“(”,“)”等字符号串来表示终结符号,而需要转而使用LPAREN, RPAREN这样的整型符号来表示。
PARSER_BEGIN(Grammar)
public class Grammar implements NodeType {
    public ParseTreeNode GetParseTree(InputStream in) throws ParseException
    {
        Grammar parser =new Grammar(in);
        return parser。Expression();
    }
}
PARSER_END(Grammar)
SKIP :
{
    " " | "	" | "
" | ""
}
TOKEN :
{
    < ID: ["a"-"z","A"-"Z","_"> ( ["a"-"z","A"-"Z","_","0"-"9"> )* >
  | < NUM: ( ["0"-"9"> )+ >
  | < PLUS:   "+" >
  | < MINUS:  "-" >
  | < TIMERS: "*" >
  | < OVER:   "/" >
  | < LPAREN: "(" >
  | < RPAREN: ")" >
}
ParseTreeNode Expression() :
{
    ParseTreeNode ParseTree = null;
    ParseTreeNode node;
}
{ 
    ( node=Simple_Expression()
        {
            if(ParseTree == null)
                ParseTree =node;
            else
            {
                ParseTreeNode t;
                t= ParseTree;
                while(t.next != null)
                    t=t.next;
                t.next = node;
            }
        }
    )*
    { return ParseTree; }
    
}
ParseTreeNode Simple_Expression() :
{
    ParseTreeNode node;
    ParseTreeNode t;
    int op;
}
{
    node=Term(){}
    (
        op=addop() t=Term()
        {
            ParseTreeNode newNode = new ParseTreeNode();
            newNode.nodetype = op;
            newNode.child[0] = node;
            newNode.child[1] = t;
            switch(op)
            {
                case PlusOP:
                    newNode.name = "Operator: +";
                    break;
                case MinusOP:
                    newNode.name = "Operator: -";
                    break;
            }
            node = newNode;
        }
    )*
    { return node; }
}
int addop() : {}
{
    { return PlusOP; }
  |{ return MinusOP; }
}
ParseTreeNode Term() :
{
    ParseTreeNode node;
    ParseTreeNode t;
    int op;
}
{
    node=Factor(){}
    (
        op=mulop() t=Factor()
        {
            ParseTreeNode newNode = new ParseTreeNode();
            newNode.nodetype = op;
            newNode.child[0] = node;
            newNode.child[1] = t;
            switch(op)
            {
                case TimersOP:
                    newNode.name = "Operator: *";
                    break;
                    case OverOP:
                    newNode.name = "Operator: /";
                    break;
            }
            node = newNode;
        }
    )*
    {
        return node;
    }
}
int mulop() :{}
{
    { return TimersOP; }
  |{ return OverOP;   }
}
ParseTreeNode Factor() :
{
    ParseTreeNode node;
    Token t;
}
{
    t=
    {
        node=new ParseTreeNode();
        node.nodetype= IDstmt;
        node.name = t.image;
        return node;
    }
    |
    t=
    {
        node=new ParseTreeNode();
        node.nodetype= NUMstmt;
        node.name = t.image;
        node.value= Integer.parseInt(t.image);
        return node;
    }
    | 
    node=Simple_Expression()
    {
        return node;
    }
}
    其中SKIP中的定义就是在进行词法分析的同时,忽略掉的记号。TOKEN中的,就是需要在做词法分析的时候,识别的词法记号。当然,这一切都是以正则表达式来表示的。
    这个例子就有多个非终结符号,可以看出,我们需要为每个非终结符号写出一个过程。不同的非终结符号的识别过程中可以互相调用。 
    以Simple_Expression()过程为例,它的产生式是Expression -> Term { addop Term
},而在javacc的输入文件格式是,它的识别是这样写的node=Term(){} ( op=addop() t=Term(){ … })*
前面说过,这里的”*”符号和正则表达式是一样的,就是0次到无限次的重复。那么Simple_Expression等于文法Term Addop
Term Addop Term Addop Term …
而Addop也就相当于PLUS和MINUS两个运算符号。这里我们在写Expression的文法的时候,同时还使用了赋值表达式,因为这个和Yacc
不同的时候,Javacc把文法识别完全地做到了函数过程中,那么如果我们要识别Simple_Expression的文法,就相当于按顺序识别Term
和Addop两个文法,而识别那个文法,就相当于调用那两个非终结符的识别函数。正是这一点,我觉得Javacc的文法识别处理上就很接近程序的操作过
程,我们不需要像YACC那样使用严格的文法表示格式,复杂的系统参数了。关于“Java LPAREN怎么用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。