递归下降分析法

2025-04-06 23:53:53
推荐回答(1个)
回答1:

# include
# include
# include
# include

// Error jmp_buf buffer
static std::jmp_buf errjb;

// Function prototypes.
int addsubt();
int multdiv();
int number();
void error();

// Global expression buffer.
static char expr[81];
static int pos;

////////////////////////////
// The main() function. //
///////////////////////////
int main()
{
int ans;

do
{
// Mark the top of the parsing descent.

if(setjmp(errjb) == 0)
{
// Initialize the string subscript.
pos = 0

// Read an expression.
std::cout << "Enter expression(0 to quit):" << std::endl;
std::cin >>expr;

// Evaluate the expression.
ans = addsubt();
if(expr[pos] != '\0')
error();
if(ans != 0)
std::cout << ans << std:endl;
}
else
{
// An error occurred.
std::cout << "Try again" << std::endl;
ans = 1;
}
}
while(ans != 0);

return 0;
}

///////////////////////////////////////////////////
// Top of recursive descent: add/subtract. //
//////////////////////////////////////////////
int addsubt()
{
int rtn = multdiv();
while(expr[pos] == '+' || expr[pos] == '-')
{
int op = expr[pos++];
int opr2 = multdiv();
if(op == '+')
rtn += opr2;
else
rtn -= opr2;
}

return rtn;
}

////////////////////////////////////////////
// Highest precedence: multiply/divide. //
///////////////////////////////////////////
int multdiv()
{
int rtn = number();
while(expr[pos] == '*' || expr[pos] == '/')
{
int op = expr[pos++];
int opr2 = number();

if(op == '*')
rtn *= opr2;
else
rtn /= opr2;
}

return rtn;
}

/////////////////////////
// Extract a number //
///////////////////////
int number()
{
int rtn;
if(expr[pos] == '(')
{
// Parenthetical expression.
pos++;
rtn = addsubt(); // Back to top.
if(expr[pos++] != ')') // Must have ')'
error();
return rtn;
}

// Extract the number.
if(!isdigit(expr[pos]))
error;
rtn = atoi(expr + pos);
while(isdigit(expr[pos]))
pos++;

return rtn;
}

////////////////////////
// Syntax error. //
//////////////////////
void error()
{
std::cout << '\r';
while(pos--) // Position error pointer.
std::cout << ' ';
std::cout << "A syntax error" << std::endl << '\a';

// Return to the top of the program.
std::longjmp(errjb,1);
}
}