mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-04 06:30:10 +08:00
Use precedence parser for expressions
This is smaller and uses less stack depth per expression (eight function calls from expr_or to get down to a unary). It's a tiny bit faster depending on how good the branch predictor is, on my machine a wash.
This commit is contained in:
parent
fdeeb62e28
commit
23a8bac7b5
3
tcc.h
3
tcc.h
@ -1434,8 +1434,7 @@ ST_FUNC void parse_mult_str (CString *astr, const char *msg);
|
|||||||
ST_FUNC void parse_asm_str(CString *astr);
|
ST_FUNC void parse_asm_str(CString *astr);
|
||||||
ST_FUNC void indir(void);
|
ST_FUNC void indir(void);
|
||||||
ST_FUNC void unary(void);
|
ST_FUNC void unary(void);
|
||||||
ST_FUNC void expr_prod(void);
|
ST_FUNC void init_prec(void);
|
||||||
ST_FUNC void expr_sum(void);
|
|
||||||
ST_FUNC void gexpr(void);
|
ST_FUNC void gexpr(void);
|
||||||
ST_FUNC int expr_const(void);
|
ST_FUNC int expr_const(void);
|
||||||
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
|
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
|
||||||
|
114
tccgen.c
114
tccgen.c
@ -5681,100 +5681,52 @@ special_math_val:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void expr_prod(void)
|
static int precedence(int tok)
|
||||||
{
|
{
|
||||||
int t;
|
switch (tok) {
|
||||||
|
case '|': return 1;
|
||||||
unary();
|
case '^': return 2;
|
||||||
while (tok == '*' || tok == '/' || tok == '%') {
|
case '&': return 3;
|
||||||
t = tok;
|
case TOK_EQ: case TOK_NE: return 4;
|
||||||
next();
|
relat: case TOK_ULT: case TOK_UGE: return 5;
|
||||||
unary();
|
case TOK_SHL: case TOK_SAR: return 6;
|
||||||
gen_op(t);
|
case '+': case '-': return 7;
|
||||||
|
case '*': case '/': case '%': return 8;
|
||||||
|
default:
|
||||||
|
if (tok >= TOK_ULE && tok <= TOK_GT)
|
||||||
|
goto relat;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void expr_sum(void)
|
static unsigned char prec[256];
|
||||||
|
ST_FUNC void init_prec(void)
|
||||||
{
|
{
|
||||||
int t;
|
int i;
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
expr_prod();
|
prec[i] = precedence(i);
|
||||||
while (tok == '+' || tok == '-') {
|
|
||||||
t = tok;
|
|
||||||
next();
|
|
||||||
expr_prod();
|
|
||||||
gen_op(t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void expr_shift(void)
|
#define precedence(i) ((unsigned)i < 256 ? prec[i] : 0)
|
||||||
|
|
||||||
|
static void expr_infix(int p)
|
||||||
{
|
{
|
||||||
int t;
|
int t = tok, p2, p3;
|
||||||
|
while ((p2 = precedence(t)) >= p) {
|
||||||
expr_sum();
|
next();
|
||||||
while (tok == TOK_SHL || tok == TOK_SAR) {
|
unary();
|
||||||
t = tok;
|
while ((p3 = precedence(tok)) > p2) {
|
||||||
next();
|
expr_infix(p3);
|
||||||
expr_sum();
|
}
|
||||||
gen_op(t);
|
gen_op(t);
|
||||||
}
|
t = tok;
|
||||||
}
|
|
||||||
|
|
||||||
static void expr_cmp(void)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
|
|
||||||
expr_shift();
|
|
||||||
while ((tok >= TOK_ULE && tok <= TOK_GT) ||
|
|
||||||
tok == TOK_ULT || tok == TOK_UGE) {
|
|
||||||
t = tok;
|
|
||||||
next();
|
|
||||||
expr_shift();
|
|
||||||
gen_op(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void expr_cmpeq(void)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
|
|
||||||
expr_cmp();
|
|
||||||
while (tok == TOK_EQ || tok == TOK_NE) {
|
|
||||||
t = tok;
|
|
||||||
next();
|
|
||||||
expr_cmp();
|
|
||||||
gen_op(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void expr_and(void)
|
|
||||||
{
|
|
||||||
expr_cmpeq();
|
|
||||||
while (tok == '&') {
|
|
||||||
next();
|
|
||||||
expr_cmpeq();
|
|
||||||
gen_op('&');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void expr_xor(void)
|
|
||||||
{
|
|
||||||
expr_and();
|
|
||||||
while (tok == '^') {
|
|
||||||
next();
|
|
||||||
expr_and();
|
|
||||||
gen_op('^');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void expr_or(void)
|
static void expr_or(void)
|
||||||
{
|
{
|
||||||
expr_xor();
|
unary();
|
||||||
while (tok == '|') {
|
expr_infix(1);
|
||||||
next();
|
|
||||||
expr_xor();
|
|
||||||
gen_op('|');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int condition_3way(void);
|
static int condition_3way(void);
|
||||||
|
2
tccpp.c
2
tccpp.c
@ -3679,6 +3679,8 @@ ST_FUNC void tccpp_new(TCCState *s)
|
|||||||
define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
|
define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
|
||||||
define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
|
define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
|
||||||
define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
|
define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
|
||||||
|
|
||||||
|
init_prec();
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void tccpp_delete(TCCState *s)
|
ST_FUNC void tccpp_delete(TCCState *s)
|
||||||
|
Loading…
Reference in New Issue
Block a user