Beispiel #1
0
  bool Parser::Impl::parseTest() {
    // test := identifier arguments
    // arguments := *argument [ test / test-list ]

    //
    // identifier
    //

    if ( !obtainToken() || atEnd() )
      return false;

    if ( token() != Lexer::Identifier )
      return false;

    if ( scriptBuilder() )
      scriptBuilder()->testStart( tokenValue() );
    consumeToken();

    //
    // *argument
    //

    if ( !obtainToken() )
      return false;

    if ( atEnd() ) // a test w/o args
      goto TestEnd;

    if ( isArgumentToken() && !parseArgumentList() ) {
      assert( error() );
      return false;
    }

    //
    // test / test-list
    //

    if ( !obtainToken() )
      return false;

    if ( atEnd() ) // a test w/o nested tests
      goto TestEnd;

    if ( token() == Lexer::Special && tokenValue() == "(" ) { // test-list
      if ( !parseTestList() ) {
        assert( error() );
        return false;
      }
    } else if ( token() == Lexer::Identifier ) { // should be test:
      if ( !parseTest() ) {
        assert( error() );
        return false;
      }
    }

  TestEnd:
    if ( scriptBuilder() )
      scriptBuilder()->testEnd();
    return true;
  }
Beispiel #2
0
bool Parser::Impl::parseBlock()
{
    // our ABNF:
    // block := "{" [ command-list ] "}"

    if(!obtainToken() || atEnd())
        return false;

    if(token() != Lexer::Special || tokenValue() != "{")
        return false;
    if(scriptBuilder())
        scriptBuilder()->blockStart();
    consumeToken();

    if(!obtainToken())
        return false;

    if(atEnd())
    {
        makeError(Error::PrematureEndOfBlock);
        return false;
    }

    if(token() == Lexer::Identifier)
    {
        if(!parseCommandList())
        {
            assert(error());
            return false;
        }
    }

    if(!obtainToken())
        return false;

    if(atEnd())
    {
        makeError(Error::PrematureEndOfBlock);
        return false;
    }

    if(token() != Lexer::Special || tokenValue() != "}")
    {
        makeError(Error::NonCommandInCommandList);
        return false;
    }
    if(scriptBuilder())
        scriptBuilder()->blockEnd();
    consumeToken();
    return true;
}
Beispiel #3
0
  bool Parser::Impl::parseArgument() {
    // argument := string-list / number / tag

    if ( !obtainToken() || atEnd() )
      return false;

    if ( token() == Lexer::Number ) {
      if ( !parseNumber() ) {
        assert( error() );
        return false;
      }
      return true;
    } else if ( token() == Lexer::Tag ) {
      if ( scriptBuilder() )
        scriptBuilder()->taggedArgument( tokenValue() );
      consumeToken();
      return true;
    } else if ( isStringToken() ) {
      if ( scriptBuilder() )
        scriptBuilder()->stringArgument( tokenValue(), token() == Lexer::MultiLineString, QString() );
      consumeToken();
      return true;
    } else if ( token() == Lexer::Special && tokenValue() == "[" ) {
      if ( !parseStringList() ) {
        assert( error() );
        return false;
      }
      return true;
    }

    return false;
  }
Beispiel #4
0
QDropboxFile::QDropboxFile(QString filename, QDropbox *api, QObject *parent) :
    QIODevice(parent),
    _conManager(this)
{
    _init(api, filename, 1024);
   obtainToken();
   connectSignals();
}
Beispiel #5
0
bool Parser::Impl::parseNumber()
{
    // The lexer returns the number including the quantifier as a
    // single token value. Here, we split is an check that the number
    // is not out of range:

    if(!obtainToken() || atEnd())
        return false;

    if(token() != Lexer::Number)
        return false;

    // number:
    unsigned long result = 0;
    unsigned int i = 0;
    const QCString s = tokenValue().latin1();
    for(const unsigned int len = s.length() ; i < len && isdigit(s[i]) ; ++i)
    {
        const unsigned long digitValue = s[i] - '0' ;
        if(willOverflowULong(result, digitValue))
        {
            makeError(Error::NumberOutOfRange);
            return false;
        }
        else
        {
            result *= 10 ;
            result += digitValue ;
        }
    }

    // optional quantifier:
    char quantifier = '\0';
    if(i < s.length())
    {
        assert(i + 1 == s.length());
        quantifier = s[i];
        const unsigned long factor = factorForQuantifier(quantifier);
        if(result > double(ULONG_MAX) / double(factor))
        {
            makeError(Error::NumberOutOfRange);
            return false;
        }
        result *= factor;
    }

    if(scriptBuilder())
        scriptBuilder()->numberArgument(result, quantifier);
    consumeToken();
    return true;
}
Beispiel #6
0
  bool Parser::Impl::parseArgumentList() {
    // our ABNF:
    // argument-list := *argument

    while ( !atEnd() ) {
      if ( !obtainToken() )
        return false;
      if ( !isArgumentToken() )
        return true;
      if ( !parseArgument() )
        return !error();
    }
    return true;
  }
Beispiel #7
0
  bool Parser::Impl::parseCommandList() {
    // our ABNF:
    // command-list := *comand

    while ( !atEnd() ) {
      if ( !obtainToken() )
        return false;
      if ( token() == Lexer::None )
        continue;
      if ( token() != Lexer::Identifier )
        return true;
      if ( !parseCommand() ) {
        assert( error() );
        return false;
      }
    }
    return true;
  }
Beispiel #8
0
  bool Parser::Impl::parseStringList() {
    // string-list := "[" string *("," string) "]" / string
    //  ;; if there is only a single string, the brackets are optional
    //
    // However, since strings are already handled separately from
    // string lists in parseArgument(), our ABNF is modified to:
    // string-list := "[" string *("," string) "]"

    if ( !obtainToken() || atEnd() )
      return false;

    if ( token() != Lexer::Special || tokenValue() != "[" )
      return false;

    if ( scriptBuilder() )
      scriptBuilder()->stringListArgumentStart();
    consumeToken();

    // generic while/switch construct for comma-separated lists. See
    // parseTestList() for another one. Any fix here is like to apply there, too.
    bool lastWasComma = true;
    while ( !atEnd() ) {
      if ( !obtainToken() )
        return false;

      switch ( token() ) {
      case Lexer::None:
        break;
      case Lexer::Special:
        assert( tokenValue().length() == 1 );
        switch ( tokenValue()[0].toLatin1() ) {
        case ']':
          consumeToken();
          if ( lastWasComma ) {
            makeError( Error::ConsecutiveCommasInStringList );
            return false;
          }
          if ( scriptBuilder() )
            scriptBuilder()->stringListArgumentEnd();
          return true;
        case ',':
          consumeToken();
          if ( lastWasComma ) {
            makeError( Error::ConsecutiveCommasInStringList );
            return false;
          }
          lastWasComma = true;
          break;
        default:
          makeError( Error::NonStringInStringList );
          return false;
        }
        break;

      case Lexer::QuotedString:
      case Lexer::MultiLineString:
        if ( !lastWasComma ) {
          makeError( Error::MissingCommaInStringList );
          return false;
        }
        lastWasComma = false;
        if ( scriptBuilder() )
          scriptBuilder()->stringListEntry( tokenValue(), token() == Lexer::MultiLineString, QString() );
        consumeToken();
        break;

      default:
        makeError( Error::NonStringInStringList );
        return false;
      }
    }

    makeError( Error::PrematureEndOfStringList );
    return false;
  }
Beispiel #9
0
 bool Parser::Impl::parseTestList() {
   // test-list := "(" test *("," test) ")"
   
   if ( !obtainToken() || atEnd() )
     return false;
   
   if ( token() != Lexer::Special || tokenValue() != "(" )
     return false;
   if ( scriptBuilder() )
     scriptBuilder()->testListStart();
   consumeToken();
   
   // generic while/switch construct for comma-separated lists. See
   // parseStringList() for another one. Any fix here is like to apply there, too.
   bool lastWasComma = true;
   while ( !atEnd() ) {
     if ( !obtainToken() )
       return false;
     
     switch ( token() ) {
     case Lexer::None:
       break;
     case Lexer::Special:
       assert( tokenValue().length() == 1 );
       assert( tokenValue()[0].toLatin1() );
       switch ( tokenValue()[0].toLatin1() ) {
       case ')':
         consumeToken();
         if ( lastWasComma ) {
           makeError( Error::ConsecutiveCommasInTestList );
           return false;
         }
         if ( scriptBuilder() )
           scriptBuilder()->testListEnd();
         return true;
       case ',':
         consumeToken();
         if( lastWasComma ) {
           makeError( Error::ConsecutiveCommasInTestList );
           return false;
         }
         lastWasComma = true;
         break;
       default:
         makeError( Error::NonStringInStringList );
         return false;
       }
       break;
       
     case Lexer::Identifier:
       if ( !lastWasComma ) {
         makeError( Error::MissingCommaInTestList );
         return false;
       } else {
         lastWasComma = false;
         if ( !parseTest() ) {
           assert( error() );
           return false;
         }
       }
       break;
       
     default:
       makeUnexpectedTokenError( Error::NonTestInTestList );
       return false;
     }
   }
   
   makeError( Error::PrematureEndOfTestList );
   return false;
 }
Beispiel #10
0
  bool Parser::Impl::parseCommand() {
    // command   := identifier arguments ( ";" / block )
    // arguments := *argument [ test / test-list ]
    // block     := "{" *command "}"
    // our ABNF:
    // block     := "{" [ command-list ] "}"

    if ( atEnd() )
      return false;

    //
    // identifier
    //

    if ( !obtainToken() || token() != Lexer::Identifier )
      return false;

    if ( scriptBuilder() )
      scriptBuilder()->commandStart( tokenValue() );
    consumeToken();

    //
    // *argument
    //

    if ( !obtainToken() )
      return false;

    if ( atEnd() ) {
      makeError( Error::MissingSemicolonOrBlock );
      return false;
    }

    if ( isArgumentToken() && !parseArgumentList() ) {
      assert( error() );
      return false;
    }

    //
    // test / test-list
    //

    if ( !obtainToken() )
      return false;

    if ( atEnd() ) {
      makeError( Error::MissingSemicolonOrBlock );
      return false;
    }

    if ( token() == Lexer::Special && tokenValue() == "(" ) { // test-list
      if ( !parseTestList() ) {
        assert( error() );
        return false;
      }
    } else if ( token() == Lexer::Identifier ) { // should be test:
      if ( !parseTest() ) {
        assert( error() );
        return false;
      }
    }

    //
    // ";" / block
    //

    if ( !obtainToken() )
      return false;

    if ( atEnd() ) {
      makeError( Error::MissingSemicolonOrBlock );
      return false;
    }

    if ( token() != Lexer::Special ) {
      makeUnexpectedTokenError( Error::ExpectedBlockOrSemicolon );
      return false;
    }

    if ( tokenValue() == ";" )
      consumeToken();
    else if ( tokenValue() == "{" ) { // block
      if ( !parseBlock() )
        return false; // it's an error since we saw '{'
    } else {
      makeError( Error::MissingSemicolonOrBlock );
      return false;
    }

    if ( scriptBuilder() )
      scriptBuilder()->commandEnd();
    return true;
  }