Esempio n. 1
0
SAWYER_EXPORT std::string
Grammar::evalArgument(TokenStream &tokens, ErrorLocation &eloc, bool requireRight) const {
    std::string retval, data;
    size_t depth = 0;
    while (!tokens.atEof()) {
        if (tokens.isa(TOK_LEFT)) {
            ++depth;
            retval += tokens.lexeme();
            tokens.consume();
        } else if (tokens.isa(TOK_RIGHT)) {
            if (0 == depth)
                break;
            --depth;
            retval += tokens.lexeme();
            tokens.consume();
        } else if (tokens.isa(TOK_FUNCTION)) {
            retval += evalFunction(tokens, eloc);
        } else {
            retval += tokens.lexeme();
            tokens.consume();
        }
    }
    if (requireRight) {
        if (!tokens.isa(TOK_RIGHT))
            throw SyntaxError("end-of-argument expected");
        tokens.consume();
    }
    if (depth > 0)
        throw SyntaxError("expected end-of-argument marker");
    return retval;
}
Esempio n. 2
0
SAWYER_EXPORT std::string
Grammar::evalFunction(TokenStream &tokens, ErrorLocation &eloc) const {
    ASSERT_require(tokens.isa(TOK_FUNCTION));
    std::string funcName = tokens.lexeme();
    ASSERT_require(funcName.size() >= 2 && '@' == funcName[0]);
    funcName = funcName.substr(1);
    tokens.consume();

    // Get the function declaration
    const Function::Ptr func = functions_.getOrDefault(funcName);
    if (!func)
        throw SyntaxError("function \"" + funcName + "\" is not declared");

    // Parse the actual arguments
    std::vector<std::string> actuals;
    while (tokens.isa(TOK_LEFT)) {
        tokens.consume();
        if (func->isMacro()) {
            actuals.push_back(readArgument(tokens, eloc, CONSUME));
        } else {
            actuals.push_back(evalArgument(tokens, eloc, CONSUME));
        }
    }
    func->validateArgs(actuals, tokens);

    ErrorLocation::Trap t(eloc, tokens, "in function \"" + funcName + "\"");
    std::string retval = func->eval(*this, actuals);
    t.passed();
    return retval;
}
Esempio n. 3
0
void parse_string_as_argument_list(caValue* str, List* output)
{
    // Read the tokens as a space-seperated list of strings.
    // TODO is to be more smart about word boundaries: spaces inside
    // quotes or parentheses shouldn't break apart items.

    TokenStream tokens;
    tokens.reset(as_cstring(str));
    
    Value itemInProgress;
    set_string(&itemInProgress, "");

    while (!tokens.finished()) {

        if (tokens.nextIs(tok_Whitespace)) {
            if (!equals_string(&itemInProgress, "")) {
                copy(&itemInProgress, list_append(output));
                set_string(&itemInProgress, "");
            }

        } else {
            string_append(&itemInProgress, tokens.nextStr().c_str());
        }

        tokens.consume();
    }

    if (!equals_string(&itemInProgress, "")) {
        copy(&itemInProgress, list_append(output));
        set_string(&itemInProgress, "");
    }
}
Esempio n. 4
0
SAWYER_EXPORT std::string
Grammar::readArgument(TokenStream &tokens, ErrorLocation &eloc, bool requireRight) const {
    std::string retval;
    size_t depth = 0;
    for (/*void*/; !tokens.atEof(); tokens.consume()) {
        if (tokens.isa(TOK_LEFT)) {
            ++depth;
        } else if (tokens.isa(TOK_RIGHT)) {
            if (0 == depth)
                break;
            --depth;
        }
        retval += tokens.lexeme();
    }
    if (requireRight) {
        if (!tokens.isa(TOK_RIGHT))
            throw SyntaxError("end-of-argument expected");
        tokens.consume();
    }
    if (depth > 0)
        throw SyntaxError("expected end-of-argument marker");
    return retval;
}