示例#1
0
struct cParseNode* _get_parse_tree(int start, struct Grammar* grammar, struct TokenStream* tokens, struct Error* error) {
    struct cParseNode* parent = parse_rule(start, grammar, tokens, error);
    if (parent == NULL) {
        return NULL;
    }
    struct cParseNode* current = parent->child;
    struct cParseNode* tmp;
    int m, ignore;
    int rule = start;
    LOG("ignore any trailing ignores\n");
    while (tokens->at < tokens->num) {
        ignore = 0;
        for (m=0;m<grammar->ignore.num;m++) {
            if (tokens->tokens[tokens->at].which == grammar->ignore.tokens[m]) {
                ignore = 1;
                break;
            }
        }
        if (ignore == 0) {
            break;
        }
        LOG("ignoring white\n");
        tmp = _new_parsenode(rule);
        tmp->token = &tokens->tokens[tokens->at];
        tmp->type = NTOKEN;
        current = append_nodes(current, tmp);
        LOG("inc token %d %d\n", tokens->at, tokens->at+1);
        tokens->at += 1;
    }
    parent->child = current;
    return parent;
}
示例#2
0
static DBusHandlerResult handle_get_nodes(DBusConnection *conn,
					  DBusMessage *message,
					  void *arg)
{
	DBusMessage *reply;
	DBusMessageIter array;
	dbus_uint32_t serial = 0;

	reply = dbus_message_new_method_return(message);
	dbus_message_iter_init_append(reply, &array);
	if (!append_nodes(CRAS_STREAM_OUTPUT, &array))
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
	if (!append_nodes(CRAS_STREAM_INPUT, &array))
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
	dbus_connection_send(conn, reply, &serial);
	dbus_message_unref(reply);

	return DBUS_HANDLER_RESULT_HANDLED;
}
示例#3
0
struct cParseNode* check_special(unsigned int rule, struct RuleSpecial special, struct cParseNode* current, struct Grammar* grammar, struct TokenStream* tokens, struct Error* error) {
    struct cParseNode* tmp;
    int at, i;
    LOG("special\n");
    INDENT();
    if (special.type == STAR) {
        LOG("star!\n");
        while (tokens->at < tokens->num) {
            at = tokens->at;
            tmp = parse_children(rule, special.option, grammar, tokens, error);
            if (tmp == NULL) {
                tokens->at = at;
                break;
            }
            current = append_nodes(current, tmp);
            if (at == tokens->at) {
                break;
            }
        }
        LOG("awesome star\n");
        DEDENT();
        return current;
    } else if (special.type == PLUS) {
        LOG("plus!\n");
        at = tokens->at;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        if (tmp == NULL) {
            tokens->at = at;
            LOG("failed plus\n");
            DEDENT();
            return NULL;
        }
        current = append_nodes(current, tmp);
        if (at == tokens->at) {
            return current;
        }
        while (tokens->at < tokens->num) {
            at = tokens->at;
            tmp = parse_children(rule, special.option, grammar, tokens, error);
            if (tmp == NULL) {
                tokens->at = at;
                break;
            }
            current = append_nodes(current, tmp);
            if (at == tokens->at) {
                break;
            }
        }
        LOG("good plus\n");
        DEDENT();
        return current;
    } else if (special.type == OR) {
        LOG("or!\n");
        at = tokens->at;
        for (i=0;i<special.option->num;i++) {
            // each of the child items with be of the special STRAIGHT option
            // type -> allowing the OR special to have a list of lists
            tmp = parse_children(rule, special.option->items[i].value.special.option, grammar, tokens, error);
            if (tmp != NULL) {
                LOG("got or...\n");
                current = append_nodes(current, tmp);
                DEDENT();
                return current;
            }
        }
        LOG("fail or\n");
        DEDENT();
        return NULL;
    } else if (special.type == QUESTION) {
        LOG("?maybe\n");
        at = tokens->at;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        LOG("done maybe children\n");
        if (tmp == NULL) {
            LOG("not taking it\n");
            tokens->at = at;
            DEDENT();
            return current;
        }
        current = append_nodes(current, tmp);
        LOG("got maybe\n");
        DEDENT();
        return current;
    } else if (special.type == NOIGNORE) {
        LOG("no ignore (initial %d)\n", grammar->rules.rules[rule].dont_ignore);
        int before_ignore = grammar->rules.rules[rule].dont_ignore;
        at = tokens->at;
        grammar->rules.rules[rule].dont_ignore = 1;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        grammar->rules.rules[rule].dont_ignore = before_ignore;
        if (tmp == NULL) {
            tokens->at = at;
            LOG("failed ignore\n");
            DEDENT();
            return NULL;
        }
        current = append_nodes(current, tmp);
        LOG("ignore success! back to %d %d", grammar->rules.rules[rule].dont_ignore, before_ignore);
        DEDENT();
        return current;
    } else if (special.type == NOT) {
        LOG("NOT\n");
        at = tokens->at;
        tmp = parse_children(rule, special.option, grammar, tokens, error);
        if (tmp == NULL) {
            if (tokens->at < tokens->num) {
                tmp = _new_parsenode(rule);
                tmp->token = &tokens->tokens[tokens->at];
                tmp->type = NTOKEN;
                tokens->at += 1;
                current = append_nodes(current, tmp);
                LOG("awesome. eating token\n");
            } else {
                LOG("not enough tokens to eat\n");
                at = tokens->at;
                return NULL;
            }
            DEDENT();
            return current;
        }
        LOG("nope, it passed\n");
        tokens->at = at;
        DEDENT();
        return NULL;
    } else {
        LOG("unknown special type: %s\n", special.type);
        DEDENT();
        return NULL;
    }
    LOG("umm shouldnt happen");
    DEDENT();
    return NULL;
}
示例#4
0
// clean
struct cParseNode* parse_children(unsigned int rule, struct RuleOption* option, struct Grammar* grammar, struct TokenStream* tokens, struct Error* error) {
    LOG("parsing children of %d (token at %d)\n", rule, tokens->at);
    struct cParseNode* current = UNINITIALIZED;
    unsigned int i = 0, m = 0;
    unsigned int at = 0;
    struct cParseNode* tmp = NULL;
    struct RuleItem* item = NULL;
    int ignore;
    INDENT();
    for (i=0;i<option->num;i++) {
        item = &option->items[i];
        if (!grammar->rules.rules[rule].dont_ignore) {
            while (tokens->at < tokens->num) {
                ignore = 0;
                for (m=0;m<grammar->ignore.num;m++) {
                    if (tokens->tokens[tokens->at].which == grammar->ignore.tokens[m]) {
                        ignore = 1;
                        break;
                    }
                }
                if (ignore == 0) {
                    break;
                }
                LOG("ignoring white\n");
                tmp = _new_parsenode(rule);
                tmp->token = &tokens->tokens[tokens->at];
                tmp->type = NTOKEN;
                current = append_nodes(current, tmp);
                LOG("inc token %d %d\n", tokens->at, tokens->at+1);
                tokens->at += 1;
            }
        }
        if (tokens->at < tokens->num) {
            LOG("At token %d '%s'\n", tokens->at, tokens->tokens[tokens->at].value);
        }
        if (item->type == RULE) {
            LOG(">RULE\n");
            /**
            if (0 && tokens->at >= tokens->num) { // disabling
                error->at = tokens->at;
                error->reason = 1;
                error->token = NULL;
                error->text = "ran out";
                // error[1] = ['ran out', rule, i, item->value.which];
                // log('not enough tokens')
                DEDENT();
                return NULL;
            }
            **/
            at = tokens->at;
            tmp = parse_rule(item->value.which, grammar, tokens, error);
            if (tmp == NULL) {
                tokens->at = at;
                if (tokens->at >= error->at && error->reason!=1 && error->reason!=4) {
                    error->at = tokens->at;
                    error->reason = 2;
                    error->token = &tokens->tokens[tokens->at];
                    error->text = "rule failed";
                    error->wanted = item->value.which;
                }
                DEDENT();
                return NULL;
            }
            current = append_nodes(current, tmp);
            continue;
        } else if (item->type == TOKEN) {
            LOG(">TOKEN\n");
            if (tokens->at >= tokens->num) {
                if (item->value.which == tokens->eof) {
                    LOG("EOF -- passing\n");
                    tmp = _new_parsenode(rule);
                    tmp->token = (struct Token*)malloc(sizeof(struct Token));
                    tmp->token->value = NULL;
                    tmp->token->which = tokens->eof;
                    tmp->token->lineno = -1;
                    tmp->token->charno = -1;
                    tmp->type = NTOKEN;
                    current = append_nodes(current, tmp);
                    continue;
                }
                LOG("no more tokens\n");
                error->at = tokens->at;
                error->reason = 1;
                error->token = NULL;
                error->text = "ran out";
                error->wanted = item->value.which;
                DEDENT();
                return NULL;
            }
            if (tokens->tokens[tokens->at].which == item->value.which) {
                LOG("got token! %d\n", item->value.which);
                tmp = _new_parsenode(rule);
                tmp->token = &tokens->tokens[tokens->at];
                tmp->type = NTOKEN;
                current = append_nodes(current, tmp);
                LOG("inc token %d %d\n", tokens->at, tokens->at+1);
                tokens->at += 1;
                continue;
            } else {
                if (tokens->at > error->at) {
                    error->at = tokens->at;
                    error->reason = 3;
                    error->token = &tokens->tokens[tokens->at];
                    error->text = "token failed";
                    error->wanted = option->items[i].value.which;
                }
                LOG("token failed (wanted %d, got %d)\n",
                        item->value.which, tokens->tokens[tokens->at].which);
                DEDENT();
                return NULL;
            }
        } else if (item->type == LITERAL) {
            LOG(">LITERAL\n");
            if (tokens->at >= tokens->num) {
                error->at = tokens->at;
                error->reason = 4;
                error->token = NULL;
                error->text = item->value.text;
                DEDENT();
                return NULL;
            }
            if (strcmp(item->value.text, tokens->tokens[tokens->at].value) == 0) {
                LOG("got literal!\n");
                tmp = _new_parsenode(rule);
                tmp->token = &tokens->tokens[tokens->at];
                tmp->type = NTOKEN;
                current = append_nodes(current, tmp);
                LOG("inc token %d %d\n", tokens->at, tokens->at+1);
                tokens->at += 1;
                continue;
            } else {
                if (tokens->at > error->at) {
                    error->at = tokens->at;
                    error->reason = 5;
                    error->token = &tokens->tokens[tokens->at];
                    error->text = item->value.text;
                }
                LOG("failed....literally: %s\n", item->value.text);
                DEDENT();
                return NULL;
            }
        } else if (item->type == SPECIAL) {
            LOG(">SPECIAL\n");
            tmp = check_special(rule, item->value.special, current, grammar, tokens, error);
            if (tmp == NULL) {
                LOG("FAIL SPECIAL\n");
                DEDENT();
                return NULL;
            }
            current = tmp;
        }
    }
    DEDENT();
    return current;
}