evalexpr: parse: use single 'ops' table
This commit is contained in:
parent
81f7d30ddd
commit
88b7f50a3a
|
@ -10,6 +10,19 @@
|
||||||
#define UNREACHABLE() __builtin_unreachable()
|
#define UNREACHABLE() __builtin_unreachable()
|
||||||
#define ARR_SIZE(Arr) (sizeof(Arr) / sizeof(*Arr))
|
#define ARR_SIZE(Arr) (sizeof(Arr) / sizeof(*Arr))
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *op;
|
||||||
|
const int kind; // Because we store different kinds of enum...
|
||||||
|
const int prio;
|
||||||
|
const enum { ASSOC_LEFT, ASSOC_RIGHT, ASSOC_NONE } assoc;
|
||||||
|
const enum { OP_INFIX, OP_PREFIX, OP_POSTFIX } fix;
|
||||||
|
} ops[] = {
|
||||||
|
# define BINOP(Op, Kind, Prio, Assoc, Fix) { #Op, Kind, Prio, Assoc, Fix },
|
||||||
|
# define PREOP(Op, Kind, Prio, Assoc, Fix) { #Op, Kind, Prio, Assoc, Fix },
|
||||||
|
# define POSTOP(Op, Kind, Prio, Assoc, Fix) { #Op, Kind, Prio, Assoc, Fix },
|
||||||
|
#include "operators.inc"
|
||||||
|
};
|
||||||
|
|
||||||
static struct ast_node *climbing_parse_internal(const char **input, int prec);
|
static struct ast_node *climbing_parse_internal(const char **input, int prec);
|
||||||
static struct ast_node *parse_operand(const char **input);
|
static struct ast_node *parse_operand(const char **input);
|
||||||
|
|
||||||
|
@ -26,13 +39,8 @@ static void skip_whitespace(const char **input)
|
||||||
|
|
||||||
static enum binop_kind char_to_binop(char c)
|
static enum binop_kind char_to_binop(char c)
|
||||||
{
|
{
|
||||||
static const struct { const char *op; const enum binop_kind kind; } ops[] = {
|
|
||||||
#define BINOP(Op, Kind, _, __, ___) { #Op, Kind },
|
|
||||||
#include "operators.inc"
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
||||||
if (c == ops[i].op[0])
|
if (ops[i].fix == OP_INFIX && c == ops[i].op[0])
|
||||||
return ops[i].kind;
|
return ops[i].kind;
|
||||||
|
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -40,14 +48,8 @@ static enum binop_kind char_to_binop(char c)
|
||||||
|
|
||||||
static enum unop_kind char_to_unop(char c)
|
static enum unop_kind char_to_unop(char c)
|
||||||
{
|
{
|
||||||
static const struct { const char *op; const enum unop_kind kind; } ops[] = {
|
|
||||||
#define PREOP(Op, Kind, _, __, ___) { #Op, Kind },
|
|
||||||
#define POSTOP(Op, Kind, _, __, ___) { #Op, Kind },
|
|
||||||
#include "operators.inc"
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
||||||
if (c == ops[i].op[0])
|
if (ops[i].fix != OP_INFIX && c == ops[i].op[0])
|
||||||
return ops[i].kind;
|
return ops[i].kind;
|
||||||
|
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -55,12 +57,8 @@ static enum unop_kind char_to_unop(char c)
|
||||||
|
|
||||||
static bool is_binop(char c)
|
static bool is_binop(char c)
|
||||||
{
|
{
|
||||||
static const char *ops[] = {
|
|
||||||
#define BINOP(Op, _, __, ___, ____) #Op,
|
|
||||||
#include "operators.inc"
|
|
||||||
};
|
|
||||||
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
||||||
if (c == ops[i][0])
|
if (ops[i].fix == OP_INFIX && c == ops[i].op[0])
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -68,13 +66,6 @@ static bool is_binop(char c)
|
||||||
|
|
||||||
static bool prec_between(const char **input, int min, int max)
|
static bool prec_between(const char **input, int min, int max)
|
||||||
{
|
{
|
||||||
static const struct { const char *op; const int prio; } ops[] = {
|
|
||||||
#define BINOP(Op, _, Priority, __, ___) { #Op, Priority },
|
|
||||||
#define PREOP(Op, _, Priority, __, ___) { #Op, Priority },
|
|
||||||
#define POSTOP(Op, _, Priority, __, ___) { #Op, Priority },
|
|
||||||
#include "operators.inc"
|
|
||||||
};
|
|
||||||
|
|
||||||
skip_whitespace(input);
|
skip_whitespace(input);
|
||||||
|
|
||||||
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
||||||
|
@ -84,17 +75,6 @@ static bool prec_between(const char **input, int min, int max)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct {
|
|
||||||
const char *op;
|
|
||||||
const int kind; // Because we store different kinds of enum...
|
|
||||||
const int prio;
|
|
||||||
const enum { ASSOC_LEFT, ASSOC_RIGHT, ASSOC_NONE } assoc;
|
|
||||||
const enum { OP_INFIX, OP_PREFIX, OP_POSTFIX } fix;
|
|
||||||
} ops[] = {
|
|
||||||
# define BINOP(Op, Kind, Prio, Assoc, Fix) { #Op, Kind, Prio, Assoc, Fix },
|
|
||||||
#include "operators.inc"
|
|
||||||
};
|
|
||||||
|
|
||||||
static int right_prec(char c)
|
static int right_prec(char c)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
for (size_t i = 0; i < ARR_SIZE(ops); ++i)
|
||||||
|
|
Loading…
Reference in a new issue