LLOOP Index | GSP Language | GSP Library | Framework Classes | Component Classes

quote.gsp

This is the verbatim text of the file "quote.gsp" part of the LLOOP package. The copyright remains with Michel MEHL. All rights reserved.



/**
 * Reads any sequence of chars enclosed by double or simple quote chars. Escape chars are supported. 
 */

token QuoteToken extends class universal::String()
  include "universal__String.h"
  alias "quote"
  declare    /* Extra declarations in token class */
  {{
    private:
      char m_cQuoteChar;
      
    protected:     
      bool getEscapeSequence(std::istream& is, char& c);
  }}
  implement  /* Extra implementations in token class */
  {{
    bool QuoteToken::getEscapeSequence(std::istream& is, char& c)
      {
	register char cnext = 0;
	unsigned char cincr = 0;

	is.get(c);   
		
	if (!is.fail())
	  switch (c) 
	    {
	    case 'a': c = 0x07; break;
	    case 'b': c = '\b'; break;
	    case 'f': c = 0x0C; break;
	    case 'n': c = '\n'; break;
	    case 'r': c = '\r'; break;
	    case 't': c = '\t'; break;
	    case 'v': c = 0x0B; break;
	    case 'x': // Hexadecimal number
		      
	      is.get(cnext);
	      if (is.fail()) return false; //abort("");// Error: nothing following \x
	      c = 0;
	      cincr = cnext - '0';
	      if (cincr <= 15) 
		{
		  c = (c << 4) + cincr;
		  is.get(cnext);
		  if (is.fail()) break; // OK: No error. 
		  cincr = cnext - '0';
		  if (cincr <= 15) 
		    {
		      c = (c << 4) + cincr;
		    } 
		  else
		    {
		      is.seekg(-1, ios::cur); // one too much read
		      break; // OK
		    }
		}
	      else
		{
		  return false; //abort("");// Error: invalid char following \x
		}
		  
	      break;

	    case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':		      
	      // If eof is reached in this case it is not a failure
	      c = c - '0';
	      is.get(cnext);
	      if (is.fail()) break; 
	      cincr = cnext - '0';
	      if (cincr <= 7) 
		{
		  c = (c << 3) + cincr;
		  is.get(cnext);
		  if (is.fail()) break; 
		  cincr = cnext - '0';
		  if (cincr <= 7) 
		    {
		      c = (c << 3) + cincr;
		    }
		  else
		    {
		      is.seekg(-1, ios::cur);// one too much read
		    }
		} 
	      else
		{
		  is.seekg(-1, ios::cur);// one too much read
		}
	      break;

	    default: // By default it is the char itself
	      break;
	    }

	return true;
      }
  }}

  parse
  {{
    char c = 0;
    register char cQuoteChar = 0;        		

    setEmpty();

    is.get(c);
    if ( c == '\'' || c == '\"')
      {        
	cQuoteChar = c;
	is.get(c);
	while (!is.fail() && (c != cQuoteChar) && (c != '\n') && (c != '\r'))
	  {
	    if (c == '\\')
	      {
		if (!QuoteToken::getEscapeSequence(is, c))
		  abort("");
	      }

	    append(c);
	    is.get(c);
	  }

	if (is.fail() || c != cQuoteChar)
	  {
	    abort("");
	  }
      }
    else
      {
	abort("");
      }

    m_cQuoteChar = cQuoteChar;
  }}

  expand
  {{
    universal::String sEscapeSequence = (*this);
    os << m_cQuoteChar << sEscapeSequence.escapeSequence()  << m_cQuoteChar;
  }} 



This file is part of the LLOOP Reversible Object-Oriented Parser Generator. Copyright (c) 2005-2006 Michel MEHL, France. All rights reserved. LLOOP is distributed by the company ERSA SaRL.


Copyright (c) 2005-2006 Michel MEHL, Haguenau, France
LLOOP version 1.1