Exemplo n.º 1
0
  bool parse(const char *subEngineString) {
    // Ignore whitespaces
    subEngineString = parseWhitespaces(subEngineString);

    // Extract engine identifier. It can be empty at this point
    const char *beginOfIdentifier = subEngineString;
    subEngineString = parseIdentifier(subEngineString);
    engineName.assign(beginOfIdentifier, subEngineString - beginOfIdentifier);

    // Ignore whitespaces
    subEngineString = parseWhitespaces(subEngineString);

    // String termination is allowed at this place
    if (!*subEngineString)
        return true;

    // Otherwise colon must be specified and engine identifier cannot be empty
    if (!engineName.length() ||  (*subEngineString != ':')
            ||  (*(subEngineString+1) == '\0'))
        LOG(FATAL) << "Wrong engine specification";

    // Process sub engines
    subEngineString++;
    while (true) {
      // Ignore separators
      subEngineString = parseSeparators(subEngineString);

      // String termination is allowed at this place
      if (!*subEngineString)
          return true;

      // Extract sub engine identifier
      const char *beginOfIdentifier = subEngineString;
      subEngineString = parseIdentifier(subEngineString);

      // Identifier can not be empty nor contain invalid characters
      if (beginOfIdentifier == subEngineString)
          return false;

      // Collect all valid sub engine names
      std::string subEngineName;
      subEngineName.assign(beginOfIdentifier,
              subEngineString - beginOfIdentifier);
      subEngines.push_back(subEngineName);
    }
  }
Exemplo n.º 2
0
static ASTPtr parseSpecifiedLengthContent(const char** fptr, const char*** wordSourcesPtr, const LengthFunc** lengthFuncsPtr) {
  assert(**fptr == '\'' || std::isdigit(**fptr) || **fptr == '#');
  ASTPtr slc;
  if (**fptr == '\'') {
    slc = parseStringLiteral(fptr);
  } else if (**fptr == '#') {
    slc = parseRepeatedCharFL(fptr, lengthFuncsPtr);
  } else {
    const char* f_at = *fptr;
    LiteralLength length = parseLiteralLength(fptr);
    if (**fptr == '\'') {
      slc.reset(new RepeatedCharLL(f_at, length, parseCharLiteral(fptr)));
    } else if (**fptr == '[') {
      Block* block = new Block(f_at, length);
      slc.reset(block);
      ++*fptr;
      parseWhitespaces(fptr); // [ is a token
      while (**fptr != ']') {
        if (**fptr == '\'' || std::isdigit(**fptr) || **fptr == '#') {
          block->addChild(parseSpecifiedLengthContent(fptr, wordSourcesPtr, lengthFuncsPtr));
        } else if (**fptr == '{') {
          block->addWords(parseWords(fptr, wordSourcesPtr));
        } else {
          throw DSLException(*fptr, "Expected ', digit, or # to begin specified-length content, "
            "or { to begin greedy-length content.");
        }
      }
      ++*fptr;
      parseWhitespaces(fptr); // ] is a token
      if (**fptr == '^') {
        parseTopOrBottomFiller(fptr, &block->topFillers, true);
        if (**fptr == 'v') {
          parseTopOrBottomFiller(fptr, &block->bottomFillers, false);
        }
      } else if (**fptr == 'v') {
        parseTopOrBottomFiller(fptr, &block->bottomFillers, false);
        if (**fptr == '^') {
          parseTopOrBottomFiller(fptr, &block->topFillers, true);
        }
      }
    } else {
      throw DSLException(*fptr, "Expected ' or [ after length specifier.");
    }
  }
  return slc;
}
Exemplo n.º 3
0
static void parseTopOrBottomFiller(const char** fptr, std::vector<FillerPtr>* fillers, bool top) {
  char firstChar = top ? '^' : 'v';
  assert(**fptr == firstChar);
  ++*fptr;
  parseWhitespaces(fptr); // ^, v are tokens
  if (**fptr != '{') {
    throw DSLException(*fptr, "Expected {.");
  }
  ++*fptr;
  parseWhitespaces(fptr); // { is a token
  parseFillers(fptr, fillers);
  if (**fptr != '}') {
    throw DSLException(*fptr, "Expected }.");
  }
  ++*fptr;
  parseWhitespaces(fptr); // } is a token
}
Exemplo n.º 4
0
static LiteralLength parseLiteralLength(const char** fptr) {
  assert(std::isdigit(**fptr));
  LiteralLength ll(parseUint(fptr), false);
  if (**fptr == 's') {
    ll.shares = true;
    ++*fptr;
  }
  parseWhitespaces(fptr);
  return ll;
}
Exemplo n.º 5
0
static FillerPtr parseStringLiteral(const char** fptr) { // TOKEN
  assert(**fptr == '\'');
  const char* f_at = *fptr;
  ++*fptr;
  std::string str;
  while (**fptr != '\'') {
    str += parseCharInsideQuotes(&*fptr, '\'');
  }
  ++*fptr;
  parseWhitespaces(fptr);
  return FillerPtr(new StringLiteral(f_at, str));
}
Exemplo n.º 6
0
static FunctionLength parseFunctionLength(const char** fptr, const LengthFunc** lengthFuncsPtr) {
  assert(**fptr == '#');
  FunctionLength fl(**lengthFuncsPtr, false);
  ++*lengthFuncsPtr;
  ++*fptr;
  if (**fptr == 's') {
    fl.shares = true;
    ++*fptr;
  }
  parseWhitespaces(fptr);
  return fl;
}
Exemplo n.º 7
0
static char parseSilhouetteCharLiteral(const char** fptr) {
  assert(**fptr == '-');
  ++*fptr;
  if (**fptr != '>') {
    throw DSLException(*fptr, "Expected > immediately after -.");
  }
  ++*fptr;
  parseWhitespaces(fptr); // -> is a token
  if (**fptr != '\'') {
    throw DSLException(*fptr, "Expected char literal after ->.");
  }
  return parseCharLiteral(fptr);
}
Exemplo n.º 8
0
static char parseCharLiteral(const char** fptr) {  // TOKEN
  assert(**fptr == '\'');
  ++*fptr;
  if (**fptr == '\'') {
    throw DSLException(*fptr, "Exected char literial; found '' instead.");
  }
  char c = parseCharInsideQuotes(&*fptr, '\'');
  if (**fptr != '\'') {
    throw DSLException(*fptr, "Expected closing ' for char literal.");
  }
  ++*fptr;
  parseWhitespaces(fptr);
  return c;
}
Exemplo n.º 9
0
static ASTPtr parseWords(const char** fptr, const char*** wordSourcesPtr) {
  assert(**fptr == '{');
  Words* words = new Words(*fptr, **wordSourcesPtr);
  ++*wordSourcesPtr;
  ASTPtr ast(words);
  ++*fptr;
  parseWhitespaces(fptr); // { is a token
  if (**fptr == 'w') {
    ++*fptr;
    parseWhitespaces(fptr); // w is a token
    if (**fptr == '-') {
      words->wordSilhouette = parseSilhouetteCharLiteral(fptr);
    }
    parseFillers(fptr, &words->interwordFillers);
  } else {
    throw DSLException(*fptr, "Expected w after {.");
  }
  if (**fptr != '}') {
    throw DSLException(*fptr, "Expected }, ->, or interword fillers.");
  }
  ++*fptr;
  parseWhitespaces(fptr); // } is a token
  return ast;
}
Exemplo n.º 10
0
static ASTPtr parseFormat(const char** fptr, const char*** wordSourcesPtr, const LengthFunc** lengthFuncsPtr) {
  parseWhitespaces(fptr);
  // Will insert all root content as children into a super-root Block.
  Block* rootsParentBlock = new Block(*fptr, LiteralLength(0, false));
  ASTPtr rootsParent(rootsParentBlock);
  while (**fptr != '\0') {
    if (**fptr == '\'' || std::isdigit(**fptr)) {
      ASTPtr root = parseSpecifiedLengthContent(fptr, wordSourcesPtr, lengthFuncsPtr);
      int rootLength = root->getFixedLength();
      if (rootLength == UNKNOWN_COL) {
        throw DSLException(root->f_at, "Root content must be fixed-length.");
      }
      rootsParentBlock->addChild(std::move(root));
      rootsParentBlock->length.value += rootLength;
    } else {
      throw DSLException(*fptr, "Expected ' or digit.");
    }
  }
  return rootsParent;
}