2017-05-03 99 views
0

我使用的JavaCC上的Java 8.需要或不是一个参数

我有以下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

您可以考虑限定单独的表达为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表达式l ike this

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

谢谢! 现在,我怎样才能定义一个程序:先定义主函数的程序,最后定义主函数的程序,主函数定义在开始和结束之间的程序? –

+0

我编辑了我的答案 –

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() ; 
    "}" 
} 
相关问题