Grammar
<expression> ::= <term> { <addop> <term> }
<term> ::= <factor> { <mulop> <factor> }
<factor> ::= ( <expression> ) | <identifier> | <literal>
<addop> ::= + | -
<mulop> ::= * | /
<identifier> ::= a | b | c | ... | z | A | B | C | ... | Z
<literal> ::= 0 | 1 | 2 | ... | 9
Valid tokens: ()+-*/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
Valid expressions: A, B, 1, A + 2, A + B, A * (B), A * (B - 2), (1)
Invalid constructs: AB, 3A, 123, A(3), A + (), A * -3
Pseudocode
MakeExpression(Tree)
1 Make a term, setting Tree to point to it
2 while the next token is '+' or '-'
3 Make an operator node, setting left child to Tree and right to NULL. (Tree points to new node)
4 Get the next token.
5 Make a term, setting the right child of Tree to point to it.
6 end while
End MakeExpression
MakeTerm(Tree)
7 Make a factor, setting Tree to point to it
8 while the next token is '*' or '/'
9 Make an operator node, setting left child to Tree and right to NULL. (Tree points to new node)
10 Get the next token.
11 Make a factor, setting the right child of Tree to point to it.
12 end while
End MakeTerm
MakeFactor(Tree)
13 if current token is '(', then
14 Get the next token
15 Make an expression, setting Tree to point to it
16 else if current token is an IDENTIFIER
17 Make an identifier node, set Tree to point to it, set left/right children to NULL.
18 else if current token is a LITERAL
19 Make a literal node, set Tree to point to it, set left/right children to NULL.
20 end if
21 Get the next token
End MakeFactor
GetNextToken
while whitespace
Increment CurrentPosition
end while
CurrentToken = Expression[CurrentPosition]
Increment CurrentPosition
End GetNextToken
Definitions
const char PLUS_OP = '+';
const char MINUS_OP = '-';
const char MULT_OP = '*';
const char DIVIDE_OP = '/';
enum Kind {OPERATOR, LITERAL, IDENTIFIER};
struct ExprNode
{
ExprNode *left; // left sub-expression
ExprNode *right; // right sub-expression
Kind kind; // kind of node this is
union
{
char op; // the operator
int value; // the literal value
char id; // the identifier
} data;
};
void MakeExprNode(ExprNode* &tree, char token, Kind kind, ExprNode* left, ExprNode* right)
{
tree = AllocateNode();
tree->left = left;
tree->right = right;
tree->kind = kind;
switch (kind)
{
case OPERATOR:
tree->data.op = token;
break;
case LITERAL:
tree->data.value = token - '0';
break;
case IDENTIFIER:
tree->data.id = token;
break;
default:
cout << "Error in ExpTree" << endl;
}
}