示例#1
0
/*********************************************************************
  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();
  }
}
示例#2
0
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;
}
示例#3
0
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*);
}
示例#4
0
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*);
}
示例#5
0
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;
}
示例#6
0
/* 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*);
}
示例#7
0
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);
}
示例#8
0
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);
  }
}
示例#9
0
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;
}
示例#10
0
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*);
}
示例#11
0
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);
  }
}
示例#12
0
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();
}