作为赋值的一部分,我需要为以下语法实现递归下降解析器;
piece ::= {stmnt ; } [lststmnt ; ]
block ::= piece
stmnt ::= assignst | whilst | ifst | forst
assignst ::= varlist = explst
whilst ::= W expr D block E
ifst ::= I expr T block [S block] E
forst ::= P varname = expr , expr [ , expr] D block E
lststmnt ::= R [explst] | K
varlist ::= varname { , varname}
explst ::= expr , {expr ,}
expr ::= term [ binop expr ] | unop expr
term ::= N | F | V | num | varname | ( expr )
binop ::= + | - | * | / | < | > | A | O
unop ::= - | & | #
varname ::= letter { letter | digit }
num ::= digit { digit }
letter ::= U | X | Y
digit ::= 0 | 1 | 2 | 3 | 4 | 5
有关语法的更多信息包括...... 1。令牌(在语法中以粗体显示)为: E F R W I D T S P K N U V X A O Y 0 1 2 3 4 5 以及 引用,; , = # &amp; ( ) &lt; &gt; - + * / 2。引用终端','以区别于元语言符号。 3. 非终端显示为小写字词。 4. 请注意,以下字符为 NOT 标记(它们是EBNF元符号): [ ] | { }
目前我的代码在我的lstsmnt,expr和term函数上标记了错误。我无法找到以正确方式表达这些部分的方法。这段代码是建立在我扩展的作业中给我的一个非常基本的模型。如果知道语法和递归下降解析的人可以帮助我并告诉我在我的代码中我做错了什么,那将非常感激。
我已经创建了下面列出的FIRST和FOLLOW;
piece ::= FIRST(stmnt) = FIRST(assignst) = FIRST(varlist) = FIRST(varname) =
FIRST(letter) ∪ FIRST(digit) ∪ FIRST(whilst) ∪ FIRST(ifst) ∪ FIRST(forst) =
{U, X, Y, 0, 1, 2, 3, 4, 5, W, I, P}
block ::= FIRST(piece) = { { }
stmnt::= FIRST(assignst) = FIRST(varlist) = FIRST(varname) = FIRST(letter) ∪
FIRST(digit) ∪ FIRST(whilst) ∪ FIRST(ifst) ∪ FIRST(forst) = {U, X, Y, 0, 1,
2, 3, 4, 5, W, I, P}
assignst::= FIRST(varlist) = FIRST(varname) = FIRST(letter) ∪ FIRST(digit) =
{U, X, Y, 0, 1, 2, 3, 4, 5}
whilst ::= {W}
ifst ::= {I}
forst ::= {P}
lststmnt ::= {R, K}
varlist::=FIRST(varname) = FIRST(letter) ∪ FIRST(digit) = {U, X, Y, 0, 1, 2,
3, 4, 5}
explst::= FIRST(expr) = N, F, V, ∪ FIRST(term) ∩ FIRST(num) = FIRST(digit) ∪
FIRST(varname) = FIRST(letter) = {U, X, Y} ∪ FIRST(digit) ∪ '(' ∪
FIRST(unop) = {N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, -, &, #, ( }
expr::= N, F, V, ∪ FIRST(term) ∩ FIRST(num) = FIRST(digit) ∪ {FIRST(varname)
= FIRST(letter) ∪ FIRST(digit) ∪ '(' ∪ FIRST(unop) = {N, F, V, 0, 1, 2, 3,
4, 5, U, X, Y, -, &, #, ( }
term ::= N, F, V, ∪ FIRST(num) = FIRST(digit) ∪ FIRST(varname) =
FIRST(letter) ∪ FIRST(digit) ∪ '(' = {N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, (
}
binop ::= {+, -, *, /, <, >, A, O}
unop ::= {-, &, #}
varname ::= FIRST(letter) ∪ FIRST(digit) = {U, X, Y, 0, 1, 2, 3, 4, 5}
num ::= FIRST(digit) = {0, 1, 2, 3, 4, 5}
letter ::= {U, X, Y}
digit ::= {0, 1, 2, 3, 4, 5}
piece ::= {$} ∪ FOLLOW(block) = { E, S }
block ::= { E, S }
stmnt ::= { ; }
assignst ::= FOLLOW(stmnt) = { ; }
whilst ::= FOLLOW(stmnt) = { ; }
ifst ::= FOLLOW(stmnt) = { ; }
forst ::= FOLLOW(stmnt) = { ; }
lststmnt ::= { ; }
varlist ::= { = }
explst ::= { = , R }
expr ::= { ), ',' D, T }
term ::= FIRST(binop) = { +, -, *, /, <, >, A, O} ∪ FOLLOW(expr) = { ), ','
D, T }
binop ::= FIRST(expr) = { N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, -, &, #, ( }
unop ::= FIRST(expr) = { N, F, V, 0, 1, 2, 3, 4, 5, U, X, Y, -, &, #, ( }
varname { = }
num ::= FOLLOW(term) = { (, ), }
letter ::= { = }
digit ::= FIRST(digit) = {0, 1, 2, 3, 4, 5}
首先,被编码的程序被设计为提示用户输入流(例如文件)。然后用户输入合法令牌流,然后输入$。程序应输出“合法”或“发现错误”(不是两者)。
import java.io.*;
import java.util.Scanner;
//--------------------------------------------
public class Recognizer
{
static String inputString;
static int index = 0;
static int errorflag = 0;
private char token()
{ return(inputString.charAt(index)); }
private void advancePtr()
{ if (index < (inputString.length()-1)) index++; }
private void match(char T)
{ if (T == token()) advancePtr(); else error(); }
private void error()
{
System.out.println("error at position: " + index);
errorflag = 1;
advancePtr();
}
//----------------------
private void piece()
{ stmnt();
match(';');
lststmnt(); }
private void block()
{ piece(); }
private void stmnt()
{ if ((token() == 'U')
|| (token() == 'X')
|| (token() == 'Y')) assignst();
else if ((token() == 'W')) whilst();
else if ((token() == 'I')) ifst();
else if ((token() == 'P')) forst(); }
private void assignst()
{ varlist();
match('=');
explst(); }
private void whilst()
{ match('W');
expr();
match('D');
block();
match('E'); }
private void ifst()
{ match('I');
expr();
match('T');
block();
match('S');
match('E'); }
private void forst()
{ match('P');
varname();
match('=');
expr();
match(',');
match('D');
block();
match('E'); }
private void lststmnt()
{ if (match('R')
explst()) {
;
} else {
match('K');
} }
private void varlist()
{ varname();
match(','); }
private void explst() ******ISSUE*********
{ expr();
match(','); }
private void expr() ******ISSUE*********
{ if (
term();
binop();
expr());
else if
(unop();
expr()); }
private void term() *******ISSUE*******
{ if ((token() == 'N')
|| (token() == 'F')
|| (token() == 'V'))
match(token());
else if num();
else if varname();
else if(token() == ('('))
match(token()); }
private void binop()
{ if ((token() == '+')
|| (token() == '-')
|| (token() == '*')
|| (token() == '/')
|| (token() == '<')
|| (token() == '>')
|| (token() == 'A')
|| (token() == 'O'))
match(token()); else error(); }
private void unop()
{ if ((token() == '-')
|| (token() == '&')
|| (token() == '#'))
match(token()); else error(); }
private void varname()
{ if ((token() == 'U')
|| (token() == 'X')
|| (token() == 'Y')) letter();
else digit(); }
private void num()
{ while ((token() == '0')
|| (token() == '1')
|| (token() == '2')
|| (token() == '3')
|| (token() == '4')
|| (token() == '5')) digit(); }
private void letter()
{ if ((token() == 'U')
|| (token() == 'X')
|| (token() == 'Y'))
match(token()); else error(); }
private void digit()
{ if ((token() == '0')
|| (token() == '1')
|| (token() == '2')
|| (token() == '3')
|| (token() == '4')
|| (token() == '5'))
match(token()); else error(); }
//----------------------
private void start()
{
expr();
match('$');
if (errorflag == 0)
System.out.println("legal." + "\n");
else
System.out.println("errors found." + "\n");
}
//----------------------
public static void main (String[] args) throws IOException
{
Recognizer rec = new Recognizer();
Scanner input = new Scanner(System.in);
System.out.print("\n" + "enter an expression: ");
inputString = input.nextLine();
rec.start();
}
}