这种EBNF方法是否正确?

时间:2014-03-11 23:33:29

标签: java parsing ebnf

我不确定我是否正在将EBNF翻译成正确的代码,所以如果有人可以看一下我很难做到的其中一种方法,那就是大。

这是EBNF语法:

   program ::= P {declare} B {statemt} ;
   declare ::= ident {, ident} : V ;
   statemt ::= assnmt | ifstmt | doloop | read | output
   assnmt  ::= ident ~ exprsn ;
   ifstmt  ::= I comprsn @ {statemt} [% {statemt}] &
   doloop  ::= D {statemt} U comprsn T
   read    ::= R ident {, ident } ;
   output  ::= O ident {, ident } ;
   comprsn ::= ( oprnd opratr oprnd )
   exprsn  ::= factor {+ factor}
   factor  ::= oprnd {* oprnd}
   oprnd   ::= integer | ident | ( exprsn )
   opratr  ::= < | = | > | !
   ident   ::= letter {char}
   char    ::= letter | digit
   integer ::= digit {digit}
   letter  ::= X | Y | Z
   digit   ::= 0 | 1

代币是:P B; ,:V~I @%&amp; D U T R O()+ *&lt; =&gt; ! X Y Z 0 1

private void statemt(){
    if((token() == 'X') || (token() == 'Y') || (token() == 'Z')){
      assnmt();
    }else if(token() == 'I'){
      ifstmt();
    }else if(token() == 'D'){
      doloop();
    }else if(token() == 'R'){
      read();
    }else if(token() == 'O'){
      output();
    }
}

如果stmt方法正确吗?

   private void ifstmt(){
     match('I');
     comprsn();
     match('@');
     while((token() == 'X') || (token() == 'Y') || (token() == 'Z')){
       statemt();
     }
     if(token() == '%'){
         match('%');
         statemt();
     }
     match('&');
   }

1 个答案:

答案 0 :(得分:1)

最好先测试以关键字开头的语句,然后在没有关键字匹配的情况下进入分配案例。这样您就不需要X,Y,Z作为关键字:

private void statemt(){
    if(token() == 'I'){
      ifstmt();
    }else if(token() == 'D'){
      doloop();
    }else if(token() == 'R'){
      read();
    }else if(token() == 'O'){
      output();
    } else {
      assnmt();
    }
}

在这个时代和语言中,我认为这些缩写没有任何正当理由。

回答有关if声明的问题:

private void ifstatement() {
    match('I');
    comprsn();
    match('@');
    statement();
    if (token() == '%') {
        statement();
    }
    if (token() != '&') {
        syntax_error("'&' expected");
    }
}

要回答关于{语句的第二个扩展名},这将在语法中表示

statement ::= '{' statement ... '}'

这是在statement()中实现的:

private void statement(){
    if (token == '{') {
        do {
            statement();
        } while (token() != '}');
    } else if(token() == 'I'){
      ifstmt();
    }else if(token() == 'D'){
      doloop();
    }else if(token() == 'R'){
      read();
    }else if(token() == 'O'){
      output();
    } else {
      assnmt();
    }
}

请注意,我完全忽略了令牌消耗的问题,因为您没有告诉我们token()match()方法的工作原理。