/********************************************************************* everything between a list bar and a rbrack is transformed in a generator structure: GENERATOR ---- GENERATOR ---- ... NULL | | GENERATOR -- | in case of an ordinary expression the right part is NULL in case of a generator the variable(list) is left and the list-expr(list) right **********************************************************************/ static void parsegenerators(int *count) { Cell *temp; for(;;) { int varcount = 0, exprcount = 0; while(tokentype == SEP) gettoken(); if(tokentype == RBRACK) break; push(temp = newcell(GENERATOR)); temp->value = getPositionCode(); (*count)++; for(;;) { parseexpression(MAXPRIO); varcount++; if(tokentype != COMMA) break; gettoken(); } if(tokentype == GENER || tokentype == ASSIGNMENT) { bool assignment = tokentype == ASSIGNMENT; do { gettoken(); parseexpression(MAXPRIO); exprcount++; if(assignment) { push(template_nil); makeinverse(LIST); } } while(tokentype == COMMA); if(exprcount != varcount) parseerror(32); push(template_nil); while(exprcount-- > 0) makeinverse(LIST); temp->right = pop(); push(template_nil); while(varcount-- > 0) makeinverse(LIST); checkpattern(temp->left = pop()); } else if(varcount > 1) parseerror(31); else temp->left = pop(); } }
bool parseinput(char s[]) { bool result = False; setchecktypevariables(NOCHECK); openinput(s); checkmemlarge(); storefunctionname(""); tokenoffside = 0; gettoken(); if(tokentype == empty) { push(template_nil); return result; } parseexpression(MAXPRIO); if(tokentype == WHERE) { gettoken(); parsewhereclause(); } if(tokentype == COLONS) result = True; else if(tokentype != empty) parseerror(19); closeinput(); initrename(""); settop(renamerec(EXP, top())); return result; }
void TestParseExpr_3(CuTest *tc) { /* Lexer data. */ char sqlexpr[] = "((((1)+2)))"; db_eetnode_t *expr; db_lexer_t lexer; lexer_init(&lexer, sqlexpr); /* Memory management data. */ db_int segment_size = 1000; unsigned char segment[segment_size]; db_query_mm_t mm; init_query_mm(&mm, segment, sizeof(segment)); /* Do the whole process. */ parseexpression(&expr, &lexer, 0, strlen(sqlexpr), &mm, 0); db_eetnode_t *np = expr; CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBINT == ((db_eetnode_dbint_t*)np)->base.type); CuAssertTrue(tc, 1 == ((db_eetnode_dbint_t*)np)->integer); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbint_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBINT == ((db_eetnode_dbint_t*)np)->base.type); CuAssertTrue(tc, 2 == ((db_eetnode_dbint_t*)np)->integer); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbint_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_OP_ADD == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_t), db_eetnode_t*); }
void TestParseExpr_16(CuTest *tc) { /* Lexer data. */ char sqlexpr[] = "MAX(LENGTH('apple'))"; db_eetnode_t *expr; db_lexer_t lexer; lexer_init(&lexer, sqlexpr); /* Memory management data. */ db_int segment_size = 1000; unsigned char segment[segment_size]; db_query_mm_t mm; init_query_mm(&mm, segment, sizeof(segment)); /* Do the whole process. */ parseexpression(&expr, &lexer, 0, strlen(sqlexpr), &mm, 0); db_eetnode_t *np = expr; printf("np->type: %d\n", np->type); fflush(stdout); CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBSTRING == np->type); CuAssertTrue(tc, 0==strcmp(((db_eetnode_dbstring_t*)np)->string, "apple")); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbstring_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_FUNC_LENGTH_DBSTRING == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_AGGR_TEMP == np->type); CuAssertTrue(tc, DB_AGGR_MAX == ((db_eetnode_aggr_temp_t*)np)->aggr_type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_aggr_temp_t), db_eetnode_t*); }
int runline(char* line, int* pc) { tokeniser_setup(line); token = tokeniser_next(); switch (token) { case TOK_PRINT:// STRING|EXPR (, STRING|EXPR) do { token = tokeniser_next(); if (token == TOK_EOL || token == TOK_ERR) { break; } if (token == TOK_STRING) { printf("%s ", tokeniser_string()); token = tokeniser_next(); } else { printf("%d ", parseexpression()); } if (token != TOK_COMMA && token != TOK_EOL) { printf("expected ','\n"); return 0; } } while (token != TOK_EOL && token != TOK_ERR); printf("\n"); break; case TOK_LET:// VAR = EXPR token = tokeniser_next(); if (token != TOK_VAR) { printf("expected variable name\n"); return 0; } char* varName = tokeniser_string(); token = tokeniser_next(); if (token != TOK_EQ) { printf("expected = after variable name\n"); return 0; } token = tokeniser_next(); int val = parseexpression(); if (token == TOK_ERR) { return 0; } setvariable(varName, token); break; } (*pc)++; return 1; }
/* Test second and third phases. This code expression does not make sense but allows for important testing. */ void TestParseExpr_17(CuTest *tc) { /* Lexer data. */ char sqlexpr[] = "LENGTH(LENGTH('string1'),T.a*2+1/3)"; db_eetnode_t *expr; db_lexer_t lexer; lexer_init(&lexer, sqlexpr); /* Memory management data. */ db_int segment_size = 1000; unsigned char segment[segment_size]; db_query_mm_t mm; init_query_mm(&mm, segment, sizeof(segment)); /* Do the whole process. */ parseexpression(&expr, &lexer, 0, strlen(sqlexpr), &mm, 0); /* Confirm that expression converted properly. */ db_eetnode_t *np = expr; CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBSTRING == np->type); CuAssertTrue(tc, 0==strcmp(((db_eetnode_dbstring_t*)np)->string, "string1")); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbstring_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_FUNC_LENGTH_DBSTRING == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_ATTR == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_attr_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBINT == ((db_eetnode_dbint_t*)np)->base.type); CuAssertTrue(tc, 2 == ((db_eetnode_dbint_t*)np)->integer); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbint_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_OP_MULT == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBINT == ((db_eetnode_dbint_t*)np)->base.type); CuAssertTrue(tc, 1 == ((db_eetnode_dbint_t*)np)->integer); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbint_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBINT == ((db_eetnode_dbint_t*)np)->base.type); CuAssertTrue(tc, 3 == ((db_eetnode_dbint_t*)np)->integer); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbint_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_OP_DIV == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_OP_ADD == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_t), db_eetnode_t*); CuAssertTrue(tc, (db_uint8)DB_EETNODE_FUNC_LENGTH_DBSTRING == np->type); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_t), db_eetnode_t*); }
static void parseexpressionclause(void) { Cell *definition = makeerror(); if(strcmp(tokenval, "=") != 0) parseerror(5); do { gettoken(); parseexpression(MAXPRIO); if(tokentype == COMMA) { gettoken(); if(strcmp(tokenval, "if") == 0) gettoken(); if(tokentype == OTHERWISE) gettoken(); else { push(makeerror()); makeinverse(_IF); parseexpression(MAXPRIO); make(_IF); } } definition = extenddefinition(definition, pop()); while(tokentype == SEP) gettoken(); if(tokentype == offside) { tokenoffside--; gettoken(); tokenoffside++; } } while(strcmp(tokenval, "=") == 0); push(definition); }
static void parsesection(int prio) { while(tokentype == OPERATOR) { Cell *temp = gettemplate(tokenval); FuncDef *fun = getfunction(temp->value); if(fun->prio > prio) break; push(temp); make(APPLY); gettoken(); if(tokentype == RPAR) break; parseexpression(fun->assoc==Left ? fun->prio-1 : fun->prio); makeinverse(APPLY); } }
static void parselefthandside(void) { parseapplication(); for(;;) if(tokentype == OPERATOR && strcmp(tokenval, "=") != 0) { parsename(); makeinverse(APPLY); } else if(tokentype == LPAR) { gettoken(); parseexpression(MAXPRIO); makeinverse(APPLY); if(tokentype != RPAR) parseerror(2); gettoken(); } else break; }
void TestParseExpr_15(CuTest *tc) { /* Lexer data. */ char sqlexpr[] = "'apple'"; db_eetnode_t *expr; db_lexer_t lexer; lexer_init(&lexer, sqlexpr); /* Memory management data. */ db_int segment_size = 1000; unsigned char segment[segment_size]; db_query_mm_t mm; init_query_mm(&mm, segment, sizeof(segment)); /* Do the whole process. */ parseexpression(&expr, &lexer, 0, strlen(sqlexpr), &mm, 0); db_eetnode_t *np = expr; CuAssertTrue(tc, (db_uint8)DB_EETNODE_CONST_DBSTRING == np->type); CuAssertTrue(tc, 0==strcmp(((db_eetnode_dbstring_t*)np)->string, "apple")); MOVEPOINTERNBYTES(np, np, sizeof(db_eetnode_dbstring_t), db_eetnode_t*); }
static void parseterm(void) { int count; switch(tokentype) { case NUMBER: if(strchr(tokenval, '.') == NULL) makeINT(atol(tokenval)); else makeREAL(atof(tokenval)); gettoken(); break; case IDENTIFIER: parsename(); break; case TYPEID: push(gettemplate(tokenval)); makecompound(STRUCT, 1); gettoken(); break; case CHARACTER: makeconstant(CHAR, tokenval[0]); gettoken(); break; case STRING: buildstring(tokenval); gettoken(); break; case LPAR: gettoken(); if(tokentype == OPERATOR && strcmp(tokenval, "-") != 0) { parsename(); if(tokentype != RPAR) { parseexpression(MAXPRIO); rotatestack(); push(gettemplate("_section")); make(APPLY); make(APPLY); } } else if(tokentype == RPAR) makeconstant(NULLTUPLE, 0); else { parseexpression(MAXPRIO); if(tokentype == COMMA) { count = 1; while(tokentype == COMMA) { gettoken(); parseexpression(MAXPRIO); count++; } makecompound(PAIR, count); } } if(tokentype != RPAR) parseerror(2); gettoken(); break; case LBRACK: parselist(); break; case LACC: count = 0; do { gettoken(); if(tokentype != IDENTIFIER) parseerror(25); push(gettemplate(tokenval)); gettoken(); if(strcmp(tokenval, "=") != 0) parseerror(5); gettoken(); parseexpression(MAXPRIO); makeinverse(ALIAS); count++; } while(tokentype == COMMA); makecompound(RECORD, count); if(tokentype != RACC) parseerror(33); gettoken(); break; default: parseerror(3); } }
static void parselist(void) { int count = 0; gettoken(); if(tokentype != RBRACK) { parseexpression(MAXPRIO); count++; } while(tokentype == COMMA) { gettoken(); parseexpression(MAXPRIO); count++; } if(tokentype == RBRACK) { push(template_nil); while(count-->0) makeinverse(LIST); } else if(tokentype == BAR && count >= 1) { push(template_nil); while(count-->0) makeinverse(LIST); count = 1; gettoken(); parsegenerators(&count); push(template_nil); while(count-->0) makeinverse(GENERATOR); } else if(tokentype == POINTS && count == 1) { gettoken(); if(tokentype == RBRACK) { push(gettemplate("nats")); make(APPLY); } else { push(gettemplate("nat")); make(APPLY); parseexpression(MAXPRIO); makeinverse(APPLY); } } else if(tokentype == POINTS && count == 2) { gettoken(); if(tokentype == RBRACK) { rotatestack(); push(gettemplate("gennats")); make(APPLY); make(APPLY); } else { rotatestack(); push(gettemplate("gennat")); make(APPLY); make(APPLY); parseexpression(MAXPRIO); makeinverse(APPLY); } } if(tokentype != RBRACK) parseerror(1); gettoken(); }