From f78ed233c0566aa786ab90ddc6fbf54abbcba97b Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 20 Jul 2012 15:20:07 +0200 Subject: [PATCH] parser_sy_pop, has to pop operators and operands and push the result --- lexer.h | 81 ++++++++++++++++++++++++++++---------------------------- parser.c | 25 +++++++++++++++++ 2 files changed, 66 insertions(+), 40 deletions(-) diff --git a/lexer.h b/lexer.h index 8715b65..9256101 100644 --- a/lexer.h +++ b/lexer.h @@ -117,6 +117,7 @@ enum { typedef struct { const char *op; + unsigned int operands; unsigned int id; unsigned int assoc; unsigned int prec; @@ -128,60 +129,60 @@ typedef struct { #define opid3(a,b,c) ((a<<16)|(b<<8)|c) static const oper_info operators[] = { - { "++", opid3('S','+','+'), ASSOC_LEFT, 16, OP_SUFFIX}, - { "--", opid3('S','-','-'), ASSOC_LEFT, 16, OP_SUFFIX}, + { "++", 1, opid3('S','+','+'), ASSOC_LEFT, 16, OP_SUFFIX}, + { "--", 1, opid3('S','-','-'), ASSOC_LEFT, 16, OP_SUFFIX}, - { ".", opid1('.'), ASSOC_LEFT, 15, 0 }, + { ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 }, - { "!", opid2('!', 'P'), ASSOC_RIGHT, 14, 0 }, - { "~", opid2('~', 'P'), ASSOC_RIGHT, 14, 0 }, - { "+", opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, - { "-", opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, - { "++", opid3('+','+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, - { "--", opid3('-','-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, -/* { "&", opid2('&','P'), ASSOC_RIGHT, 14, OP_PREFIX }, */ + { "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, 0 }, + { "~", 1, opid2('~', 'P'), ASSOC_RIGHT, 14, 0 }, + { "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "++", 1, opid3('+','+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "--", 1, opid3('-','-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, +/* { "&", 1, opid2('&','P'), ASSOC_RIGHT, 14, OP_PREFIX }, */ - { "*", opid1('*'), ASSOC_LEFT, 13, 0 }, - { "/", opid1('/'), ASSOC_LEFT, 13, 0 }, - { "%", opid1('%'), ASSOC_LEFT, 13, 0 }, + { "*", 2, opid1('*'), ASSOC_LEFT, 13, 0 }, + { "/", 2, opid1('/'), ASSOC_LEFT, 13, 0 }, + { "%", 2, opid1('%'), ASSOC_LEFT, 13, 0 }, - { "+", opid1('+'), ASSOC_LEFT, 12, 0 }, - { "-", opid1('-'), ASSOC_LEFT, 12, 0 }, + { "+", 2, opid1('+'), ASSOC_LEFT, 12, 0 }, + { "-", 2, opid1('-'), ASSOC_LEFT, 12, 0 }, - { "<<", opid2('<','<'), ASSOC_LEFT, 11, 0 }, - { ">>", opid2('>','>'), ASSOC_LEFT, 11, 0 }, + { "<<", 2, opid2('<','<'), ASSOC_LEFT, 11, 0 }, + { ">>", 2, opid2('>','>'), ASSOC_LEFT, 11, 0 }, - { "<", opid1('<'), ASSOC_LEFT, 10, 0 }, - { ">", opid1('>'), ASSOC_LEFT, 10, 0 }, - { "<=", opid2('<','='), ASSOC_LEFT, 10, 0 }, - { ">=", opid2('>','='), ASSOC_LEFT, 10, 0 }, + { "<", 2, opid1('<'), ASSOC_LEFT, 10, 0 }, + { ">", 2, opid1('>'), ASSOC_LEFT, 10, 0 }, + { "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0 }, + { ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0 }, - { "==", opid2('=','='), ASSOC_LEFT, 9, 0 }, - { "!=", opid2('!','='), ASSOC_LEFT, 9, 0 }, + { "==", 2, opid2('=','='), ASSOC_LEFT, 9, 0 }, + { "!=", 2, opid2('!','='), ASSOC_LEFT, 9, 0 }, - { "&", opid1('&'), ASSOC_LEFT, 8, 0 }, + { "&", 2, opid1('&'), ASSOC_LEFT, 8, 0 }, - { "^", opid1('^'), ASSOC_LEFT, 7, 0 }, + { "^", 2, opid1('^'), ASSOC_LEFT, 7, 0 }, - { "|", opid1('|'), ASSOC_LEFT, 6, 0 }, + { "|", 2, opid1('|'), ASSOC_LEFT, 6, 0 }, - { "&&", opid2('&','&'), ASSOC_LEFT, 5, 0 }, + { "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 }, - { "||", opid2('|','|'), ASSOC_LEFT, 4, 0 }, + { "||", 2, opid2('|','|'), ASSOC_LEFT, 4, 0 }, - { "?", opid2('?',':'), ASSOC_RIGHT, 3, 0 }, + { "?", 3, opid2('?',':'), ASSOC_RIGHT, 3, 0 }, - { "=", opid1('='), ASSOC_RIGHT, 2, 0 }, - { "+=", opid2('+','='), ASSOC_RIGHT, 2, 0 }, - { "-=", opid2('-','='), ASSOC_RIGHT, 2, 0 }, - { "*=", opid2('*','='), ASSOC_RIGHT, 2, 0 }, - { "/=", opid2('/','='), ASSOC_RIGHT, 2, 0 }, - { "%=", opid2('%','='), ASSOC_RIGHT, 2, 0 }, - { ">>=", opid3('>','>','='), ASSOC_RIGHT, 2, 0 }, - { "<<=", opid3('<','<','='), ASSOC_RIGHT, 2, 0 }, - { "&=", opid2('&','='), ASSOC_RIGHT, 2, 0 }, - { "^=", opid2('^','='), ASSOC_RIGHT, 2, 0 }, - { "|=", opid2('|','='), ASSOC_RIGHT, 2, 0 }, + { "=", 2, opid1('='), ASSOC_RIGHT, 2, 0 }, + { "+=", 2, opid2('+','='), ASSOC_RIGHT, 2, 0 }, + { "-=", 2, opid2('-','='), ASSOC_RIGHT, 2, 0 }, + { "*=", 2, opid2('*','='), ASSOC_RIGHT, 2, 0 }, + { "/=", 2, opid2('/','='), ASSOC_RIGHT, 2, 0 }, + { "%=", 2, opid2('%','='), ASSOC_RIGHT, 2, 0 }, + { ">>=", 2, opid3('>','>','='), ASSOC_RIGHT, 2, 0 }, + { "<<=", 2, opid3('<','<','='), ASSOC_RIGHT, 2, 0 }, + { "&=", 2, opid2('&','='), ASSOC_RIGHT, 2, 0 }, + { "^=", 2, opid2('^','='), ASSOC_RIGHT, 2, 0 }, + { "|=", 2, opid2('|','='), ASSOC_RIGHT, 2, 0 }, }; const size_t operator_count = (sizeof(operators) / sizeof(operators[0])); diff --git a/parser.c b/parser.c index 170e332..e03fc8f 100644 --- a/parser.c +++ b/parser.c @@ -209,10 +209,35 @@ static sy_elem syop(const oper_info *op) { static bool parser_sy_pop(parser_t *parser, shynt *sy) { + const oper_info *op; + ast_expression *vals[3]; + size_t i; + if (!sy->ops_count) { parseerror(parser, "internal error: missing operator"); return false; } + + op = &operators[sy->ops[sy->ops_count-1].etype - 1]; + + if (sy->out_count < op->operands) { + parseerror(parser, "internal error: not enough operands"); + return false; + } + + sy->ops_count--; + + sy->out_count -= op->operands; + for (i = 0; i < op->operands; ++i) + vals[i] = sy->out[sy->out_count+i].out; + + switch (op->id) + { + default: + parseerror(parser, "internal error: unhandled operand"); + return false; + } + return true; } -- 2.39.2