Esempio n. 1
0
/* Reading the pattern itself */
static int
lex_pattern(usenet_parser_t self, int ch)
{
    /* Watch for EOF or linefeed */
    if (ch == EOF || ch == '\n') {
        /* Null-terminate the token */
        if (append_char(self, '\0') < 0) {
            return -1;
        }

        /* Do something interesting with the expression */
        if (accept_expression(self, self->field, self->operator,
                              self->token) < 0) {
            return -1;
        }

        /* This is also the end of the group entry */
        if (accept_group(self, self->has_not, self->group) < 0) {
            return -1;
        }

        free(self->group);

        /* Let the start state deal with the EOF or linefeed */
        return lex_start(self, ch);
    }

    /* Watch for the escape character */
    if (ch == '\\') {
        self->state = lex_pattern_esc;
        return 0;
    }

    /* Watch for other whitespace */
    if (isspace(ch)) {
        /* Record the position of the whitespace for later trimming */
        self->token_mark = self->token_pointer;
        self->state = lex_pattern_ws;
        return append_char(self, ch);
    }

    /* Watch for a separator */
    if (ch == '/') {
        /* Null-terminate the token */
        if (append_char(self, '\0') < 0) {
            return -1;
        }

        /* Do something interesting with the expression */
        self->token_pointer = self->token;
        self->state = lex_field_start;
        return accept_expression(self, self->field, self->operator,
                                 self->token);
    }

    /* Anything else is part of the pattern */
    return append_char(self, ch);
}
Esempio n. 2
0
/* Reading trailing whitespace after a pattern */
static int
lex_pattern_ws(usenet_parser_t self, int ch)
{
    /* Watch for EOF and newline */
    if (ch == EOF || ch == '\n') {
        /* Trim off the trailing whitespace */
        *self->token_mark = '\0';

        /* Do something interesting with the expression */
        if (accept_expression(self, self->field, self->operator,
                              self->token) < 0) {
            return -1;
        }

        /* This is also the end of the group entry */
        if (accept_group(self, self->has_not, self->group) < 0) {
            return -1;
        }

        free(self->group);

        /* Let the start state deal with the EOF or newline */
        return lex_start(self, ch);
    }

    /* Skip any other whitespace */
    if (isspace(ch)) {
        return append_char(self, ch);
    }

    /* Watch for an escape character */
    if (ch == '\\') {
        self->state = lex_pattern_esc;
        return 0;
    }

    /* Watch for a separator */
    if (ch == '/') {
        /* Trim off the trailing whitespace */
        *self->token_mark = '\0';

        /* Do something interesting with the expression */
        self->token_pointer = self->token;
        self->state = lex_field_start;
        return accept_expression(self, self->field, self->operator,
                                 self->token);
    }

    /* Anything else is more of the pattern */
    self->state = lex_pattern;
    return append_char(self, ch);
}
Esempio n. 3
0
shared_ptr<Statement>
Parser::accept_var_statement(const shared_ptr<Environment> environment) {
    if (!accept(Token(Token::IDENTIFIER, "var")))
        return nullptr;
    Token identifier;
    expect(Token::IDENTIFIER, identifier);
    shared_ptr<Expression> initializer = make_shared<UndefinedValue>();
    if (accept(Token(Token::OPERATOR, "="))
            && !(initializer = accept_expression(environment)))
        expected("initializer");
    expect(Token::SEMICOLON);
    return make_shared<VarStatement>(identifier.string, initializer);
}