static bool parse_action(struct action_context *ctx) { if (ctx->lexer->token.type != LEX_T_ID) { action_syntax_error(ctx, NULL); return false; } enum lex_type lookahead = lexer_lookahead(ctx->lexer); if (lookahead == LEX_T_EQUALS || lookahead == LEX_T_EXCHANGE || lookahead == LEX_T_LSQUARE) { parse_set_action(ctx); } else if (lexer_match_id(ctx->lexer, "next")) { parse_next_action(ctx); } else if (lexer_match_id(ctx->lexer, "output")) { emit_resubmit(ctx, ctx->ap->output_ptable); } else if (lexer_match_id(ctx->lexer, "ip.ttl")) { if (lexer_match(ctx->lexer, LEX_T_DECREMENT)) { add_prerequisite(ctx, "ip"); ofpact_put_DEC_TTL(ctx->ofpacts); } else { action_syntax_error(ctx, "expecting `--'"); } } else if (lexer_match_id(ctx->lexer, "ct_next")) { emit_ct(ctx, true, false); } else if (lexer_match_id(ctx->lexer, "ct_commit")) { emit_ct(ctx, false, true); } else { action_syntax_error(ctx, "expecting action"); } if (!lexer_match(ctx->lexer, LEX_T_SEMICOLON)) { action_syntax_error(ctx, "expecting ';'"); } return !ctx->error; }
static void parse_actions(struct action_context *ctx) { /* "drop;" by itself is a valid (empty) set of actions, but it can't be * combined with other actions because that doesn't make sense. */ if (ctx->lexer->token.type == LEX_T_ID && !strcmp(ctx->lexer->token.s, "drop") && lexer_lookahead(ctx->lexer) == LEX_T_SEMICOLON) { lexer_get(ctx->lexer); /* Skip "drop". */ lexer_get(ctx->lexer); /* Skip ";". */ if (ctx->lexer->token.type != LEX_T_END) { action_syntax_error(ctx, "expecting end of input"); } return; } while (ctx->lexer->token.type != LEX_T_END) { if (ctx->lexer->token.type != LEX_T_ID) { action_syntax_error(ctx, NULL); break; } enum lex_type lookahead = lexer_lookahead(ctx->lexer); if (lookahead == LEX_T_EQUALS || lookahead == LEX_T_EXCHANGE || lookahead == LEX_T_LSQUARE) { parse_set_action(ctx); } else if (lexer_match_id(ctx->lexer, "next")) { parse_next_action(ctx); } else if (lexer_match_id(ctx->lexer, "output")) { emit_resubmit(ctx, ctx->output_ptable); } else if (lexer_match_id(ctx->lexer, "ip4.ttl")) { if (lexer_match(ctx->lexer, LEX_T_DECREMENT)) { struct expr *e = expr_parse_string("ip4", ctx->symtab, &ctx->error); ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, e); ofpact_put_DEC_TTL(ctx->ofpacts); } else { action_syntax_error(ctx, "expecting `--'"); } } else if (lexer_match_id(ctx->lexer, "ct_next")) { emit_ct(ctx, true, false); } else if (lexer_match_id(ctx->lexer, "ct_commit")) { emit_ct(ctx, false, true); } else { action_syntax_error(ctx, "expecting action"); } if (!lexer_match(ctx->lexer, LEX_T_SEMICOLON)) { action_syntax_error(ctx, "expecting ';'"); } if (ctx->error) { return; } } }