]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/script/scripttokeniser.h
Merge branch 'NateEag-master-patch-12920' into 'master'
[xonotic/netradiant.git] / libs / script / scripttokeniser.h
index ba4a0787e76d715541c891dfd44bfde9ff4b4f51..8744aec35e59c1e68e4a6e51dff5923d3d5f7500 100644 (file)
 /*
-Copyright (C) 2001-2006, William Joseph.
-All Rights Reserved.
+   Copyright (C) 2001-2006, William Joseph.
+   All Rights Reserved.
 
-This file is part of GtkRadiant.
+   This file is part of GtkRadiant.
 
-GtkRadiant 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.
+   GtkRadiant 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.
 
-GtkRadiant 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.
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
-#if !defined(INCLUDED_SCRIPT_SCRIPTTOKENISER_H)
+#if !defined( INCLUDED_SCRIPT_SCRIPTTOKENISER_H )
 #define INCLUDED_SCRIPT_SCRIPTTOKENISER_H
 
 #include "iscriplib.h"
 
 class ScriptTokeniser : public Tokeniser
 {
-  enum CharType
-  {
-    eWhitespace,
-    eCharToken,
-    eNewline,
-    eCharQuote,
-    eCharSolidus,
-    eCharStar,
-    eCharSpecial,
-  };
+enum CharType
+{
+       eWhitespace,
+       eCharToken,
+       eNewline,
+       eCharQuote,
+       eCharSolidus,
+       eCharStar,
+       eCharSpecial,
+};
 
-  typedef bool (ScriptTokeniser::*Tokenise)(char c);
+typedef bool ( ScriptTokeniser::*Tokenise )( char c );
 
-  Tokenise m_stack[3];
-  Tokenise* m_state;
-  SingleCharacterInputStream<TextInputStream> m_istream;
-  std::size_t m_scriptline;
-  std::size_t m_scriptcolumn;
+Tokenise m_stack[3];
+Tokenise* m_state;
+SingleCharacterInputStream<TextInputStream> m_istream;
+std::size_t m_scriptline;
+std::size_t m_scriptcolumn;
 
-  char m_token[MAXTOKEN];
-  char* m_write;
+char m_token[MAXTOKEN];
+char* m_write;
 
-  char m_current;
-  bool m_eof;
-  bool m_crossline;
-  bool m_unget;
-  bool m_emit;
+char m_current;
+bool m_eof;
+bool m_crossline;
+bool m_unget;
+bool m_emit;
 
-  bool m_special;
+bool m_special;
 
-  CharType charType(const char c)
-  {
-    switch(c)
-    {
-    case '\n': return eNewline;
-    case '"': return eCharQuote;
-    case '/': return eCharSolidus;
-    case '*': return eCharStar;
-    case '{': case '(': case '}': case ')': case '[': case ']': case ',': case ':': return (m_special) ? eCharSpecial : eCharToken;
-    }
-    
-    if(c > 32)
-    {
-      return eCharToken;
-    }
-    return eWhitespace;
-  }
+CharType charType( const char c ){
+       switch ( c )
+       {
+       case '\n': return eNewline;
+       case '"': return eCharQuote;
+       case '/': return eCharSolidus;
+       case '*': return eCharStar;
+       case '{': case '(': case '}': case ')': case '[': case ']': case ',': case ':': return ( m_special ) ? eCharSpecial : eCharToken;
+       }
+
+       if ( c > 32 ) {
+               return eCharToken;
+       }
+       return eWhitespace;
+}
 
-  Tokenise state()
-  {
-    return *m_state;
-  }
-  void push(Tokenise state)
-  {
-    ASSERT_MESSAGE(m_state != m_stack + 2, "token parser: illegal stack push");
-    *(++m_state) = state;
-  }
-  void pop()
-  {
-    ASSERT_MESSAGE(m_state != m_stack, "token parser: illegal stack pop");
-    --m_state;
-  }
-  void add(const char c)
-  {
-    if(m_write < m_token + MAXTOKEN - 1)
-    {
-      *m_write++ = c;
-    }
-  }
-  void remove()
-  {
-    ASSERT_MESSAGE(m_write > m_token, "no char to remove");
-    --m_write;
-  }
+Tokenise state(){
+       return *m_state;
+}
+void push( Tokenise state ){
+       ASSERT_MESSAGE( m_state != m_stack + 2, "token parser: illegal stack push" );
+       *( ++m_state ) = state;
+}
+void pop(){
+       ASSERT_MESSAGE( m_state != m_stack, "token parser: illegal stack pop" );
+       --m_state;
+}
+void add( const char c ){
+       if ( m_write < m_token + MAXTOKEN - 1 ) {
+               *m_write++ = c;
+       }
+}
+void remove(){
+       ASSERT_MESSAGE( m_write > m_token, "no char to remove" );
+       --m_write;
+}
 
-  bool tokeniseDefault(char c)
-  {
-    switch(charType(c))
-    {
-    case eNewline:
-      if(!m_crossline)
-      {
-        globalErrorStream() << Unsigned(getLine()) << ":" << Unsigned(getColumn()) << ": unexpected end-of-line before token\n";
-        return false;
-      }
-      break;
-    case eCharToken:
-    case eCharStar:
-      push(Tokenise(&ScriptTokeniser::tokeniseToken));
-      add(c);
-      break;
-    case eCharSpecial:
-      push(Tokenise(&ScriptTokeniser::tokeniseSpecial));
-      add(c);
-      break;
-    case eCharQuote:
-      push(Tokenise(&ScriptTokeniser::tokeniseQuotedToken));
-      break;
-    case eCharSolidus:
-      push(Tokenise(&ScriptTokeniser::tokeniseSolidus));
-      break;
-    default:
-      break;
-    }
-    return true;
-  }
-  bool tokeniseToken(char c)
-  {
-    switch(charType(c))
-    {
-    case eNewline:
-    case eWhitespace:
-    case eCharQuote:
-    case eCharSpecial:
-      pop();
-      m_emit = true; // emit token
-      break;
-    case eCharSolidus:
-#if 0 //SPoG: ignore comments in the middle of tokens. 
-      push(Tokenise(&ScriptTokeniser::tokeniseSolidus));
-      break;
+bool tokeniseDefault( char c ){
+       switch ( charType( c ) )
+       {
+       case eNewline:
+               if ( !m_crossline ) {
+                       globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line before token\n";
+                       return false;
+               }
+               break;
+       case eCharToken:
+       case eCharStar:
+               push( Tokenise( &ScriptTokeniser::tokeniseToken ) );
+               add( c );
+               break;
+       case eCharSpecial:
+               push( Tokenise( &ScriptTokeniser::tokeniseSpecial ) );
+               add( c );
+               break;
+       case eCharQuote:
+               push( Tokenise( &ScriptTokeniser::tokeniseQuotedToken ) );
+               break;
+       case eCharSolidus:
+               push( Tokenise( &ScriptTokeniser::tokeniseSolidus ) );
+               break;
+       default:
+               break;
+       }
+       return true;
+}
+bool tokeniseToken( char c ){
+       switch ( charType( c ) )
+       {
+       case eNewline:
+       case eWhitespace:
+       case eCharQuote:
+       case eCharSpecial:
+               pop();
+               m_emit = true; // emit token
+               break;
+       case eCharSolidus:
+#if 0 //SPoG: ignore comments in the middle of tokens.
+               push( Tokenise( &ScriptTokeniser::tokeniseSolidus ) );
+               break;
 #endif
-    case eCharToken:
-    case eCharStar:
-      add(c);
-      break;
-    default:
-      break;
-    }
-    return true;
-  }
-  bool tokeniseQuotedToken(char c)
-  {
-    switch(charType(c))
-    {
-    case eNewline:
-      if(m_crossline)
-      {
-        globalErrorStream() << Unsigned(getLine()) << ":" << Unsigned(getColumn()) << ": unexpected end-of-line in quoted token\n";
-        return false;
-      }
-      break;
-    case eWhitespace:
-    case eCharToken:
-    case eCharSolidus:
-    case eCharStar:
-    case eCharSpecial:
-      add(c);
-      break;
-    case eCharQuote:
-      pop();
-      push(Tokenise(&ScriptTokeniser::tokeniseEndQuote));
-      break;
-    default:
-      break;
-    }
-    return true;
-  }
-  bool tokeniseSolidus(char c)
-  {
-    switch(charType(c))
-    {
-    case eNewline:
-    case eWhitespace:
-    case eCharQuote:
-    case eCharSpecial:
-      pop();
-      add('/');
-      m_emit = true; // emit single slash
-      break;
-    case eCharToken:
-      pop();
-      add('/');
-      add(c);
-      break;
-    case eCharSolidus:
-      pop();
-      push(Tokenise(&ScriptTokeniser::tokeniseComment));
-      break; // dont emit single slash
-    case eCharStar:
-      pop();
-      push(Tokenise(&ScriptTokeniser::tokeniseBlockComment));
-      break; // dont emit single slash
-    default:
-      break;
-    }
-    return true;
-  }
-  bool tokeniseComment(char c)
-  {
-    if(c == '\n')
-    {
-      pop();
-      if(state() == Tokenise(&ScriptTokeniser::tokeniseToken))
-      {
-        pop();
-        m_emit = true; // emit token immediatly preceding comment
-      }
-    }
-    return true;
-  }
-  bool tokeniseBlockComment(char c)
-  {
-    if(c == '*')
-    {
-      pop();
-      push(Tokenise(&ScriptTokeniser::tokeniseEndBlockComment));
-    }
-    return true;
-  }
-  bool tokeniseEndBlockComment(char c)
-  {
-    switch(c)
-    {
-    case '/':
-      pop();
-      if(state() == Tokenise(&ScriptTokeniser::tokeniseToken))
-      {
-        pop();
-        m_emit = true; // emit token immediatly preceding comment
-      }
-      break; // dont emit comment
-    case '*':
-      break; // no state change
-    default:
-      pop();
-      push(Tokenise(&ScriptTokeniser::tokeniseBlockComment));
-      break;
-    }
-    return true;
-  }
-  bool tokeniseEndQuote(char c)
-  {
-    pop();
-    m_emit = true; // emit quoted token
-    return true;
-  }
-  bool tokeniseSpecial(char c)
-  {
-    pop();
-    m_emit = true; // emit single-character token
-    return true;
-  }
+       case eCharToken:
+       case eCharStar:
+               add( c );
+               break;
+       default:
+               break;
+       }
+       return true;
+}
+bool tokeniseQuotedToken( char c ){
+       switch ( charType( c ) )
+       {
+       case eNewline:
+               if ( m_crossline ) {
+                       globalErrorStream() << Unsigned( getLine() ) << ":" << Unsigned( getColumn() ) << ": unexpected end-of-line in quoted token\n";
+                       return false;
+               }
+               break;
+       case eWhitespace:
+       case eCharToken:
+       case eCharSolidus:
+       case eCharStar:
+       case eCharSpecial:
+               add( c );
+               break;
+       case eCharQuote:
+               pop();
+               push( Tokenise( &ScriptTokeniser::tokeniseEndQuote ) );
+               break;
+       default:
+               break;
+       }
+       return true;
+}
+bool tokeniseSolidus( char c ){
+       switch ( charType( c ) )
+       {
+       case eNewline:
+       case eWhitespace:
+       case eCharQuote:
+       case eCharSpecial:
+               pop();
+               add( '/' );
+               m_emit = true; // emit single slash
+               break;
+       case eCharToken:
+               pop();
+               add( '/' );
+               add( c );
+               break;
+       case eCharSolidus:
+               pop();
+               push( Tokenise( &ScriptTokeniser::tokeniseComment ) );
+               break; // dont emit single slash
+       case eCharStar:
+               pop();
+               push( Tokenise( &ScriptTokeniser::tokeniseBlockComment ) );
+               break; // dont emit single slash
+       default:
+               break;
+       }
+       return true;
+}
+bool tokeniseComment( char c ){
+       if ( c == '\n' ) {
+               pop();
+               if ( state() == Tokenise( &ScriptTokeniser::tokeniseToken ) ) {
+                       pop();
+                       m_emit = true; // emit token immediatly preceding comment
+               }
+       }
+       return true;
+}
+bool tokeniseBlockComment( char c ){
+       if ( c == '*' ) {
+               pop();
+               push( Tokenise( &ScriptTokeniser::tokeniseEndBlockComment ) );
+       }
+       return true;
+}
+bool tokeniseEndBlockComment( char c ){
+       switch ( c )
+       {
+       case '/':
+               pop();
+               if ( state() == Tokenise( &ScriptTokeniser::tokeniseToken ) ) {
+                       pop();
+                       m_emit = true; // emit token immediatly preceding comment
+               }
+               break; // dont emit comment
+       case '*':
+               break; // no state change
+       default:
+               pop();
+               push( Tokenise( &ScriptTokeniser::tokeniseBlockComment ) );
+               break;
+       }
+       return true;
+}
+bool tokeniseEndQuote( char c ){
+       pop();
+       m_emit = true; // emit quoted token
+       return true;
+}
+bool tokeniseSpecial( char c ){
+       pop();
+       m_emit = true; // emit single-character token
+       return true;
+}
 
-  /// Returns true if a token was successfully parsed.
-  bool tokenise()
-  {
-    m_write = m_token;
-    while(!eof())
-    {
-      char c = m_current;
+/// Returns true if a token was successfully parsed.
+bool tokenise(){
+       m_write = m_token;
+       while ( !eof() )
+       {
+               char c = m_current;
 
-      if(!((*this).*state())(c))
-      {
-        // parse error
-        m_eof = true;
-        return false;
-      }
-      if(m_emit)
-      {
-        m_emit = false;
-        return true;
-      }
+               if ( !( ( *this ).*state() )( c ) ) {
+                       // parse error
+                       m_eof = true;
+                       return false;
+               }
+               if ( m_emit ) {
+                       m_emit = false;
+                       return true;
+               }
 
-      if(c == '\n')
-      {
-        ++m_scriptline;
-        m_scriptcolumn = 1;
-      }
-      else
-      {
-        ++m_scriptcolumn;
-      }
+               if ( c == '\n' ) {
+                       ++m_scriptline;
+                       m_scriptcolumn = 1;
+               }
+               else
+               {
+                       ++m_scriptcolumn;
+               }
 
-      m_eof = !m_istream.readChar(m_current);
-    }
-    return m_write != m_token;
-  }
+               m_eof = !m_istream.readChar( m_current );
+       }
+       return m_write != m_token;
+}
 
-  const char* fillToken()
-  {
-    if(!tokenise())
-    {
-      return 0;
-    }
+const char* fillToken(){
+       if ( !tokenise() ) {
+               return 0;
+       }
 
-    add('\0');
-    return m_token;
-  }
+       add( '\0' );
+       return m_token;
+}
 
-  bool eof()
-  {
-    return m_eof;
-  }
+bool eof(){
+       return m_eof;
+}
 
 public:
-  ScriptTokeniser(TextInputStream& istream, bool special)
-    : m_state(m_stack),
-    m_istream(istream),
-    m_scriptline(1),
-    m_scriptcolumn(1),
-    m_crossline(false),
-    m_unget(false),
-    m_emit(false),
-    m_special(special)
-  {
-    m_stack[0] = Tokenise(&ScriptTokeniser::tokeniseDefault);
-    m_eof = !m_istream.readChar(m_current);
-    m_token[MAXTOKEN - 1] = '\0';
-  }
-  void release()
-  {
-    delete this;
-  }
-  void nextLine()
-  {
-    m_crossline = true;
-  }
-  const char* getToken()
-  {
-    if(m_unget)
-    {
-      m_unget = false;
-      return m_token;
-    }
-    
-    return fillToken();
-  }
-  void ungetToken()
-  {
-    ASSERT_MESSAGE(!m_unget, "can't unget more than one token");
-    m_unget = true;
-  }
-  std::size_t getLine() const
-  {
-    return m_scriptline;
-  }
-  std::size_t getColumn() const
-  {
-    return m_scriptcolumn;
-  }
+ScriptTokeniser( TextInputStream& istream, bool special )
+       : m_state( m_stack ),
+       m_istream( istream ),
+       m_scriptline( 1 ),
+       m_scriptcolumn( 1 ),
+       m_crossline( false ),
+       m_unget( false ),
+       m_emit( false ),
+       m_special( special ){
+       m_stack[0] = Tokenise( &ScriptTokeniser::tokeniseDefault );
+       m_eof = !m_istream.readChar( m_current );
+       m_token[MAXTOKEN - 1] = '\0';
+}
+void release(){
+       delete this;
+}
+void nextLine(){
+       m_crossline = true;
+}
+const char* getToken(){
+       if ( m_unget ) {
+               m_unget = false;
+               return m_token;
+       }
+
+       return fillToken();
+}
+void ungetToken(){
+       ASSERT_MESSAGE( !m_unget, "can't unget more than one token" );
+       m_unget = true;
+}
+std::size_t getLine() const {
+       return m_scriptline;
+}
+std::size_t getColumn() const {
+       return m_scriptcolumn;
+}
 };
 
 
-inline Tokeniser& NewScriptTokeniser(TextInputStream& istream)
-{
-  return *(new ScriptTokeniser(istream, true));
+inline Tokeniser& NewScriptTokeniser( TextInputStream& istream ){
+       return *( new ScriptTokeniser( istream, true ) );
 }
 
-inline Tokeniser& NewSimpleTokeniser(TextInputStream& istream)
-{
-  return *(new ScriptTokeniser(istream, false));
+inline Tokeniser& NewSimpleTokeniser( TextInputStream& istream ){
+       return *( new ScriptTokeniser( istream, false ) );
 }
 
 #endif