Пример #1
0
double primary(){
	Token t = ts.get();
	switch(t.kind){
		case '(':				// '(' Expression ')'を処理する
			{
				double d = expression();
				t = ts.get();
				if(t.kind != ')') error("')' expected");
				return d;			
			}
		case number:					// 数字を表す
			return t.value;				// 数字の値を返す
		case name:
			{
				Token t2 = ts.get();
				if(t2.kind == '='){				// 変数に値を代入
					double d = expression();
					st.set_value(t.name, d);
					return d;
				}			
				else{
					ts.putback(t2);
					return st.get_value(t.name);	// 変数の値を返す
				}
			}
		case '-':
			return -primary();
		case '+':
			return primary();
		default:
			error("primary expected");
	}
}
double primary()
{
	Token t = ts.get();
	switch (t.kind) {
	// Handles expressions in parentheses.
	case '(':
	{	double d = expression();
		t = ts.get();
		if (t.kind != ')') {
			ts.end();
			error("')' expected");
		}
		return d;
	}
	// This handles unary + or -
	case '-':
		return - primary();
	case '+':
		return + primary();
	case NUMBER:
		return t.value;
	case VAR:
		return variables.get_value(t.name);
	case SQRT:	{
		t=ts.get();
		if(t.kind!='(') {
			ts.end();
			error("sqrt: sqrt must be of the form sqrt(expression)");
		}
		ts.unget(t);
		double d = primary();
		if(d<0) {
			ts.end();
			error("sqrt: cannot take square root of a negative number");
		}
		return sqrt(d);
	}
	default:
		ts.end();
		error("primary expected");
	}
}
double primary() // Processes semicolons, numbers and returns variables
{
	Token t = ts.get(); // Get a character
	switch (t.kind) {
	case '(': 
	{	double d = expression(); // Perform calculations in semicolons
		t = ts.get(); // Get a ')' closing character
		if (t.kind != ')') error("')' expected"); // If there wasn't any ')' return an error
		return d;
	}
	case sqrts: // Calculate square root of number or group of numbers
	{
		return squareroot();
	}
	case pows:
	{
		return pow();
	}
	case '-': // For negative digits
		return - primary(); // Return negative digit
	case number: // If Token is a number
		if(narrow_cast<int>(t.value)) return t.value; // Return the number
	case name: // If Token is a name of variable
	{	
		string s = t.name; // Save name of variable
		t = ts.get();
		if (t.kind == assign) names.set_value(s,expression()); // If there is an assignment symbol then update the value of variable
		else ts.unget(t);
		return names.get_value(s); // Return the value of the variable
	}
	case help:
		return primary();
	default:
		error("primary expected"); // Return an error if an inappropriate character was provided
	}
}