// -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4 -*- // $Header: /srv/cvs/sources/mpak/mpak/include/mpak/spec/Attic/lexer.tcc,v 1.1 2003/07/28 18:20:26 pbgavin Exp $ // mpak - the advanced package manager // ecstacy - extended c++ portable operating system interface library // Copyright (C) 2003 Peter Gavin // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef __MPAK__LEXER_TCC__ #define __MPAK__LEXER_TCC__ #include namespace mpak { namespace spec { template const ecstacy::size_type basic_lexer::tab_size = 8; template typename basic_lexer::token basic_lexer:: next_token (void) { unsigned int state = 0; int_type c; const ctype_type &ct = std::use_facet (this->buf_->getloc ()); ecstacy::size_type token_line = this->line_; ecstacy::size_type token_column = this->column_; std::basic_string token_value; while (1) { c = this->next_char (); switch (state) { case 0: // start if (traits_type::eq (c, ct.widen (' '))) { ++token_column; state = 0; } else if (traits_type::eq (c, ct.widen ('\t'))) { token_column += tab_size; state = 0; } else if (traits_type::eq (c, ct.widen ('\n'))) { token_value.push_back (c); return token (token::type_endl, token_value, token_line, token_column); } else if (ct.is (std::ctype_base::alpha, c) || (traits_type::eq (c, ct.widen('_')))) { token_value.push_back (c); state = 1; } else if (traits_type::eq (c, ct.widen ('{'))) { token_value.push_back (c); return token (token::type_block_start, token_value, token_line, token_column); } else if (traits_type::eq (c, ct.widen ('}'))) { token_value.push_back (c); return token (token::type_block_end, token_value, token_line, token_column); } else if (traits_type::eq (c, ct.widen ('\"'))) { ++token_column; state = 3; } else if (traits_type::eq (c, ct.widen ('['))) { ++token_column; state = 5; } else if (traits_type::eq (c, ct.widen ('='))) { token_value.push_back (c); return token (token::type_equals, token_value, token_line, token_column); } else if (traits_type::eq (c, ct.widen ('\\'))) { ++token_column; state = 9; } else if (traits_type::eq_int_type (c, traits_type::eof ())) { return token (token::type_eof, token_value, token_line, token_column); } else { token_value.push_back (c); return token (token::type_none, token_value, token_line, token_column); } break; case 1: // identifier if (ct.is (std::ctype_base::alnum, c) || traits_type::eq (c, ct.widen ('_'))) { token_value.push_back (c); state = 1; } else { this->putback_char (c); return token (token::type_identifier, token_value, token_line, token_column); } break; case 3: // quoted string contents if (traits_type::eq (c, ct.widen ('\\'))) { state = 4; } else if (traits_type::eq (c, ct.widen ('\"'))) { return token (token::type_string, token_value, token_line, token_column); } else if (traits_type::eq_int_type (c, traits_type::eof ())) { ecstacy::util::throw_exception (failure ("eof in string")); } else { token_value.push_back (c); state = 3; } break; case 4: // string escape if (traits_type::eq_int_type (c, traits_type::eof ())) { ecstacy::util::throw_exception (failure ("eof in string")); } else { token_value.push_back (c); state = 3; } break; case 5: // bracketed string test if (traits_type::eq (c, ct.widen ('['))) { ++token_column; state = 6; } else { this->putback_char (c); token_value.push_back (ct.widen ('[')); return token (token::type_none, token_value, token_line, token_column); } break; case 6: // bracketed string contents if (traits_type::eq (c, ct.widen ('\\'))) { state = 7; } else if (traits_type::eq (c, ct.widen (']'))) { state = 8; } else if (traits_type::eq_int_type (c, traits_type::eof ())) { ecstacy::util::throw_exception (failure ("eof in string")); } else { token_value.push_back (c); state = 6; } break; case 7: // bracketed string escape if (traits_type::eq_int_type (c, traits_type::eof ())) { ecstacy::util::throw_exception (failure ("eof in string")); } else { token_value.push_back (c); state = 6; } break; case 8: // bracketed string end if (traits_type::eq (c, ct.widen (']'))) { return token (token::type_string, token_value, token_line, token_column); } else if (traits_type::eq_int_type (c, traits_type::eof ())) { ecstacy::util::throw_exception (failure ("eof in string")); } else { this->putback_char (c); token_value.push_back (ct.widen (']')); state = 6; } break; case 9: // line continuation if (traits_type::eq_int_type (c, ct.widen ('\n'))) { token_column = 0; ++token_line; state = 0; } else { ecstacy::util::throw_exception (failure ("invalid \\ character")); } default: // shouldn't ever get here ecstacy::util::throw_exception (std::logic_error ("what the fuck?!?")); } } } } } #endif // ifndef __MPAK__LEXER_TCC__