是否要求参数

时间:2017-05-03 14:07:02

标签: java bnf javacc formal-languages

我在Java 8上使用JavaCC。

我有以下BNF表格:

Program -> ( Definition )* EOF
Definition -> ( FUNCTION_DEF ) ( FUNCTION_NAME ) ( PARAMATER_NAME ) ( OPEN_B ) ( FUNCTION_BODY ) ( CLOSE_B ) 

使用以下词法分析器

TOKEN : { < EOL : "\n" | "\r" | "\r\n" > }
TOKEN : { < FUNCTION_DEF : "DEF" > }
TOKEN : { < FUNCTION_NAME : ( ["A"-"Z"] )+ > }
TOKEN : { < PARAMATER_NAME : ( ["a"-"z"] )+ > }
TOKEN : { < OPEN_B : "{" > }
TOKEN : { < CLOSE_B : "}" > }
TOKEN : { < SPACE : " " > }

作为输入,我有以下内容:

DEF ABC x { x+1 }
DEF MAIN { ABC(1) }

我的解析器抛出一个解析错误,因为它显然需要一个参数名称。如果函数名称不是MAIN,我怎么能设法要求参数名?

由于

2 个答案:

答案 0 :(得分:2)

您可以考虑为MAIN函数定义一个单独的表达式,然后将其作为可选部分添加到程序的定义中:

Program -> ( MainDefinition )? ( Definition )* EOF
Definition -> ( FUNCTION_DEF ) ( FUNCTION_NAME ) ( PARAMATER_NAME ) ( OPEN_B ) ( FUNCTION_BODY ) ( CLOSE_B )
MainDefinition -> ( FUNCTION_DEF ) "MAIN" ( OPEN_B ) ( FUNCTION_BODY ) ( CLOSE_B )

修改

要允许MAIN位于其他函数定义的开头,结尾或中间,您只需更改Program这样的表达式

Program -> ( Definition )* ( MainDefinition )? ( Definition )* EOF

答案 1 :(得分:1)

如果参数缺失且函数名称不是MAIN,您可以使参数成为可选参数并报告错误。

void definition() :
{
    Token t ;
}
{   <FUNCTION_DEF>
    t=<FUNCTION_NAME>
    (
        <PARAMETER_NAME>
    |
        {if( ! "MAIN".equals( t.image ) ) {
            throw new ParseException( "parameter name is required" ) ;
        }
    )
    "{"
    functionBody() ;
    "}"
}

你也可以使用语义预测

void definition() :
{
    Token t ;
}
{   <FUNCTION_DEF>
    t=<FUNCTION_NAME>
    (
        LOOKAHEAD( { "MAIN".equals( t.image ) } ) 
        (<PARAMETER_NAME>)?
    |
        <PARAMETER_NAME>
    )
    "{"
    functionBody() ;
    "}"
}