我不确定我是否正在将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('&');
}
答案 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()
方法的工作原理。