/* Lexer.cc -- simple lexer for 8-puzzle test language. -*- c++ -*- Copyright (C) 2007 Casey Marshall */ #include #include #include "Lexer.h" static std::string inputString; static int inputIndex; void Lexer::setInputString(std::string& input) { inputString = input; inputIndex = 0; } void Lexer::nextToken(LexerInterface *lex) { if (inputString.length() <= inputIndex) { lex->type = TOK_EOF; return; } while (true) { char c = inputString[inputIndex]; std::cerr << "process char " << c << std::endl; switch ((c = inputString[inputIndex++])) { case '+': lex->type = TOK_PLUS; return; case '-': lex->type = TOK_MINUS; return; case '*': lex->type = TOK_TIMES; return; case '/': lex->type = TOK_DIVIDE; return; case 'e': lex->type = TOK_EDGE; return; case 'm': lex->type = TOK_MANHATTAN; return; case 'M': lex->type = TOK_MANHATTAN2; return; case 'n': lex->type = TOK_NEIGHBOR; return; case 'N': lex->type = TOK_NEIGHBOR2; return; case '(': lex->type = TOK_LPAREN; return; case ')': lex->type = TOK_RPAREN; return; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { std::string val; val.append(1, c); bool saw_dot = false; for (; inputIndex < inputString.length(); inputIndex++) { char cc = inputString[inputIndex]; if (isdigit(cc)) val.append(1, cc); else if (cc == '.') { if (saw_dot) { throw "malformed input; two decimals seen in a double"; } saw_dot = true; val.append(1, cc); } else break; } double *value = (double *) malloc(sizeof(double)); std::istringstream in(val); in >> (*value); lex->type = TOK_LITERAL; lex->sval = (SemanticValue) value; } return; default: if (!isspace(c)) throw "invalid character in input"; } } } string Lexer::tokenDesc() const { return string(""); } string Lexer::tokenKindDesc(int kind) const { return string(""); }