#include <parse.hpp>
Public Member Functions | |
parser (std::istream &input) | |
bool | get_expr (double &result) |
Private Member Functions | |
std::string | charify (char c) |
bool | get_number (double &result) |
bool | get_primary (double &result) |
bool | get_mult_expr (double &result) |
Private Attributes | |
std::istream & | input_ |
std::ctype< char > const & | ctype_ |
Definition at line 17 of file parse.hpp.
parser::parser | ( | std::istream & | input | ) |
bool parser::get_expr | ( | double & | result | ) |
Read one expression and store the result in result
.
result | Where to store the result of the expression. |
parse_error | for various syntax and other errors |
Definition at line 109 of file parse.cpp.
References get_mult_expr(), and input_.
Referenced by get_primary(), and parse_loop().
00110 { 00111 if (not get_mult_expr(result)) 00112 return false; 00113 char c; 00114 while (input_ >> c) { 00115 if (c != '+' and c != '-') { 00116 input_.unget(); 00117 return true; 00118 } else { 00119 double right; 00120 if (not get_mult_expr(right)) 00121 throw parse_error("syntax error: unterminated expression. Expected a multiplicative-exprssion after " + c); 00122 if (c == '+') 00123 result += right; 00124 else 00125 result -= right; 00126 } 00127 } 00128 return true; 00129 }
std::string parser::charify | ( | char | c | ) | [private] |
Convert a characer to a readable form.
c | The character |
c
is readable. Definition at line 10 of file parse.cpp.
References ctype_.
Referenced by get_number(), and get_primary().
00011 { 00012 if (c == '\a') return "\'\\a\'"; 00013 if (c == '\b') return "\'\\b\'"; 00014 if (c == '\f') return "\'\\f\'"; 00015 if (c == '\n') return "\'\\n\'"; 00016 if (c == '\r') return "\'\\r\'"; 00017 if (c == '\t') return "\'\\t\'"; 00018 if (c == '\v') return "\'\\v\'"; 00019 if (c == '\'') return "\'\\'\'"; 00020 if (c == '\\') return "\'\\\\\'"; 00021 00022 if (ctype_.is(ctype_.print, c)) 00023 return std::string("\'") + c + '\''; 00024 else { 00025 std::ostringstream stream; 00026 stream << "'\\x" << std::hex; 00027 stream.fill('0'); 00028 stream.width(2); 00029 stream << (std::char_traits<char>::to_int_type(c) & 0xFF) << '\''; 00030 return stream.str(); 00031 } 00032 }
bool parser::get_number | ( | double & | result | ) | [private] |
Parse a number.
result | Store the number here |
Definition at line 37 of file parse.cpp.
References charify(), and input_.
Referenced by get_primary().
00038 { 00039 std::string token; 00040 char c; 00041 if (not input_.get(c)) 00042 return false; 00043 if (c == '+' or c == '-') { 00044 token += c; 00045 if (not input_.get(c)) 00046 throw parse_error("unterminated number: expected a digit after the sign"); 00047 } 00048 if (c < '0' or c > '9') { 00049 input_.unget(); 00050 throw parse_error("syntax error: expected digit, got " + charify(c)); 00051 } 00052 while (c >= '0' and c <= '9') { 00053 token += c; 00054 if (not input_.get(c)) { 00055 std::istringstream tmp(token); 00056 // If the value overflows, return false. 00057 return (tmp >> result); 00058 } 00059 } 00060 if (c == '.') { 00061 token += c; 00062 if (not input_.get(c)) 00063 throw parse_error("unterminated number: expected digit after the decimal point"); 00064 if (c < '0' or c > '9') { 00065 input_.unget(); 00066 throw parse_error("syntax error: expected digit after decimal point, got " + charify(c)); 00067 } 00068 while (c >= '0' and c <= '9') { 00069 token += c; 00070 if (not input_.get(c)) { 00071 std::istringstream tmp(token); 00072 // If the value overflows or is otherwise invalid, return false. 00073 return (tmp >> result); 00074 } 00075 } 00076 } 00077 if (c == 'e' or c == 'E') { 00078 token += c; 00079 if (not input_.get(c)) 00080 throw parse_error("unterminated number: expected digit in the exponent"); 00081 if (c == '-' or c == '+') { 00082 token += c; 00083 if (not input_.get(c)) 00084 throw parse_error("unterminated number: expected digit after sign in the exponent"); 00085 } 00086 if (c < '0' or c > '9') { 00087 input_.unget(); 00088 throw parse_error("syntax error: expected digit in the exponent, got " + charify(c)); 00089 } 00090 while (c >= '0' and c <= '9') { 00091 token += c; 00092 if (not input_.get(c)) { 00093 std::istringstream tmp(token); 00094 // If the value overflows or is otherwise invalid, return false. 00095 return (tmp >> result); 00096 } 00097 } 00098 } 00099 input_.unget(); 00100 00101 std::istringstream tmp(token); 00102 // If the value overflows or is otherwise invalid, return false. 00103 return (tmp >> result); 00104 }
bool parser::get_primary | ( | double & | result | ) | [private] |
Parse a primary expression. A primary is a parenthesized expression or a numeric literal.
result | Store the number here |
Definition at line 161 of file parse.cpp.
References charify(), get_expr(), get_number(), and input_.
Referenced by get_mult_expr().
00162 { 00163 char c; 00164 if (not (input_ >> c)) 00165 // Can't read one character, so must be end-of-file 00166 return false; 00167 else if (c == '(') { 00168 if (not get_expr(result)) 00169 return false; 00170 if (not (input_ >> c)) 00171 throw parse_error("syntax error: EOF when expecting ')'"); 00172 else if (c != ')') 00173 throw parse_error("syntax error: expected ')', but got " + charify(c)); 00174 else 00175 return true; 00176 } else { 00177 input_.unget(); 00178 return get_number(result); 00179 } 00180 }
bool parser::get_mult_expr | ( | double & | result | ) | [private] |
Parse a multiplicative expression.
result | Store the number here |
Definition at line 134 of file parse.cpp.
References get_primary(), and input_.
Referenced by get_expr().
00135 { 00136 if (not get_primary(result)) 00137 return false; 00138 char c; 00139 while (input_ >> c) { 00140 if (c != '*' and c != '/') { 00141 input_.unget(); 00142 return true; 00143 } else { 00144 double right; 00145 if (not get_primary(right)) 00146 throw parse_error("syntax error: unterminated expression. Expected a primary after " + c); 00147 if (c == '*') 00148 result *= right; 00149 else if (right == 0.0) 00150 throw parse_error("division by zero"); 00151 else 00152 result /= right; 00153 } 00154 } 00155 return true; 00156 }
std::istream& parser::input_ [private] |
Definition at line 55 of file parse.hpp.
Referenced by get_expr(), get_mult_expr(), get_number(), and get_primary().
std::ctype<char> const& parser::ctype_ [private] |