/******************************************************************************
* File: Expression.strain
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* A strain file to lex simple arithmetic expressions into their component
* strings.
*
* You can find the strain tool online at
*
* http://www.keithschwarz.com/strain/
*/
#include <string>
#include <sstream>
#include <stdexcept>
using namespace std;
/* Function: ValidateNumber(const string& number);
* Usage: ValidateNumber("137"); // No effect
* ValidateNumber("10000000000000000000000000000"); // Throw exception
* ---------------------------------------------------------------------------
* Given a string representation of a number, returns whether that string can
* be converted into a valid integer. If it cannot (i.e. it's too big or too
* small), throws an invalid_argument exception.
*/
void ValidateNumber(const string& number) {
/* Construct a stringstream to hold the number. */
stringstream converter(number);
/* Try reading out a number. On failure, report an error. */
int result;
if (!(converter >> result))
throw invalid_argument("Number out of range: " + number);
}
%%
/* No postamble code required. */
%%
Token: string
%%
\-[digit][digit]*
/* Explicitly negative number. */
ValidateNumber(TOKEN);
RETURN(Token, TOKEN);
[digit][digit]*
/* Implicitly positive number. */
ValidateNumber(TOKEN);
RETURN(Token, TOKEN);
\+[digit][digit]*
/* Explicitly positive number; drop the + before returning. */
ValidateNumber(TOKEN.substr(1));
RETURN(Token, TOKEN.substr(1));
\+|\-|\*|\/|\%
/* Operators come back "as-is." */
RETURN (Token, TOKEN);
[space][space]*
/* Take no action; we just want to skip spaces. */