parser Class Reference

#include <parse.hpp>

List of all members.

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_


Detailed Description

Parser class template.

Definition at line 17 of file parse.hpp.


Constructor & Destructor Documentation

parser::parser ( std::istream &  input  ) 

Constructor. Save the input stream.

Parameters:
input The input stream

Definition at line 5 of file parse.cpp.

00006 : input_(input),
00007   ctype_(std::use_facet<std::ctype<char> >(input.getloc()))
00008 {}


Member Function Documentation

bool parser::get_expr ( double &  result  ) 

Read one expression and store the result in result.

Parameters:
result Where to store the result of the expression.
Returns:
true to continue or false to end the loop
Exceptions:
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.

Parameters:
c The character
Returns:
A C++-style character literal that ensures 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.

Parameters:
result Store the number here
Returns:
true to continue parsing or false to stop (end of file or error)

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.

Parameters:
result Store the number here
Returns:
true to continue parsing or false to stop (end of file or error)

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.

Parameters:
result Store the number here
Returns:
true to continue parsing or false to stop (end of file or error)

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 }


Member Data Documentation

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]

Definition at line 56 of file parse.hpp.

Referenced by charify().


The documentation for this class was generated from the following files:
Generated on Sun Nov 30 10:04:19 2008 for Calculator by  doxygen 1.5.3