Beispiel #1
0
AST* ParseAssignment(ParserState* parser) {
	AST *lvalue;
	enum Semantic sem = SEM_ASSIGNMENT;

	if(parser->currentToken.type == TOKEN_LOCAL) {
		Match(parser, TOKEN_LOCAL);
		sem = SEM_LOCAL_ASSIGNMENT;
	}

	if(parser->nextToken.type == TOKEN_LEFT_SQUARE_BRACKET) {
		lvalue = ParseArrayIndexing(parser);
	} else if(parser->nextToken.type == TOKEN_DOT) {
		lvalue = ParseField(parser);
	} else {
		Value *id = Match(parser, TOKEN_ID);
		lvalue = CreateASTNode(SEM_ID, id);
	}

	Match(parser, TOKEN_ASSIGNMENT);

	AST *expr = ParseExpression(parser);

	AST *assignment = CreateASTNode(sem, VALUE_EMPTY);

	AddASTChild(assignment, lvalue);
	AddASTChild(assignment, expr);

	return assignment;
}
Beispiel #2
0
AST* ParseLogicalExpression(ParserState* parser) {
	AST* valueNode = ParseValue(parser);
	AST* lexpNode = NULL;

	switch(parser->currentToken.type) {
		case TOKEN_LT:
			lexpNode = CreateASTNode(SEM_LT, VALUE_EMPTY);
			break;
		case TOKEN_EQ:
			lexpNode = CreateASTNode(SEM_EQ, VALUE_EMPTY);
			break;
		case TOKEN_GT:
			lexpNode = CreateASTNode(SEM_GT, VALUE_EMPTY);
			break;
		case TOKEN_LTE:
			lexpNode = CreateASTNode(SEM_LTE, VALUE_EMPTY);
			break;
		case TOKEN_GTE:
			lexpNode = CreateASTNode(SEM_GTE, VALUE_EMPTY);
			break;
		default:
			return valueNode;
	}

	Advance(parser);

	AST* rhs = ParseValue(parser);

	AddASTChild(lexpNode, valueNode);
	AddASTChild(lexpNode, rhs);

	return lexpNode;
}
Beispiel #3
0
/* Without priorities yet */
AST* ParseCondition(ParserState* parser) {
	if(parser->currentToken.type == TOKEN_NOT) {
		AST* notCond = CreateASTNode(SEM_NOT, VALUE_EMPTY);
		Match(parser, TOKEN_NOT);

		AddASTChild(notCond, ParseLogicalExpression(parser));

		return notCond;
	} else {
		AST* lexp = ParseLogicalExpression(parser);
		AST* rhs;

		enum TokenType type = parser->currentToken.type;

		if(type == TOKEN_AND || type == TOKEN_OR) {
			Match(parser, type);
			rhs = ParseCondition(parser);

			AST *log_node = CreateASTNode(type == TOKEN_AND ? SEM_AND : SEM_OR, VALUE_EMPTY);
			AddASTChild(log_node, lexp);
			AddASTChild(log_node, rhs);

			return log_node;
		}

		return lexp;
	}
}
Beispiel #4
0
ASTTree ParseCommand(char **cmdTokens, int tokenCnt) {
  if (tokenCnt <= 0) return NULL;

  int i;
  for (i = tokenCnt-1; i >= 0; i--) {
    char *token = cmdTokens[i];

    if (strcmp(token, "|") == 0) {
      // Create a pipe node
      cmdTokens[i] = NULL;
      ASTNode *pipeNode = CreateASTNode();
      pipeNode->type = PipeCommand;
      pipeNode->u.pipe.leftCommand = ParseCommand(cmdTokens, i);
      pipeNode->u.pipe.rightCommand = ParseCommand(cmdTokens+i+1, tokenCnt-i-1);
      return pipeNode;
    } else if (strcmp(token, ">") == 0) {
      // If > appears, must be > file in the end. Nothing more.
      // don't support > sth < sth2
      if (cmdTokens[i+1] == NULL) {
        perror("Wrong syntax: > should be followed by a file name.");
        return NULL;
      }
      cmdTokens[i] = NULL;
      ASTNode *outNode = CreateASTNode();
      outNode->type = OutRedirCommand;
      outNode->u.out.command = ParseCommand(cmdTokens, tokenCnt-2);
      outNode->u.out.outFile = cmdTokens[i+1];
      return outNode;
    } else if (strcmp(token, ">>") == 0) {
      if (cmdTokens[i+1] == NULL) {
        perror("Wrong syntax: >> should be followed by a file name.");
        return NULL;
      }
      cmdTokens[i] = NULL;
      ASTNode *appNode = CreateASTNode();
      appNode->type = OutAppendCommand;
      appNode->u.app.command = ParseCommand(cmdTokens, tokenCnt-2);
      appNode->u.app.appendFile = cmdTokens[i+1];
      return appNode;
    } else if (strcmp(token, "<") == 0) {
      if (cmdTokens[i+1] == NULL) {
        perror("Wrong syntax: < should be followed by a file name.");
        return NULL;
      }
      cmdTokens[i] = NULL;
      ASTNode *inpNode = CreateASTNode();
      inpNode->type = InpRedirCommand;
      inpNode->u.inp.command = ParseCommand(cmdTokens, tokenCnt-2);
      inpNode->u.inp.inpFile = cmdTokens[i+1];
      return inpNode;
    }
  }
  // Prim Command
  ASTNode *primNode = CreateASTNode();
  primNode->type = PrimCommand;
  primNode->u.prim.cmdTokens = cmdTokens;
  return primNode;
}
Beispiel #5
0
AST* ParseField(ParserState* parser) {
	Value* id = Match(parser, TOKEN_ID);

	Match(parser, TOKEN_DOT);

	Value* field_name = Match(parser, TOKEN_FIELD);

	AST* ast = CreateASTNode(SEM_FIELD, id);
	AddASTChild(ast, CreateASTNode(SEM_CONSTANT, field_name));

	return ast;
}
Beispiel #6
0
AST* ParseObject(ParserState* parser) {
	if(parser->currentToken.type == TOKEN_OBJECT) {
		Match(parser, TOKEN_OBJECT);

		return CreateASTNode(SEM_OBJECT, VALUE_EMPTY);
	} else {
		Match(parser, TOKEN_NEW);

		AST* constructor_call = ParseFunctionCall(parser);

		AST* ast = CreateASTNode(SEM_NEW, VALUE_EMPTY);
		AddASTChild(ast, constructor_call);

		return ast;
	}
}
Beispiel #7
0
AST* ParsePrint(ParserState* parser) {
	Match(parser, TOKEN_PRINT);

	AST* printNode = CreateASTNode(SEM_PRINT, VALUE_EMPTY);
	AST* exprNode = ParseExpression(parser);

	printNode->child = exprNode;

	return printNode;
}
Beispiel #8
0
AST* ParseOperatorList(ParserState* parser) {
	AST *operators = CreateASTNode(SEM_EMPTY, VALUE_EMPTY);

	while(parser->currentToken.type != TOKEN_END) {
		AST *op = ParseOperator(parser);
		AddASTChild(operators, op);
	}

	return operators;
}
Beispiel #9
0
AST* ParseReturn(ParserState* parser) {
	Match(parser, TOKEN_RETURN);

	AST* node = CreateASTNode(SEM_RETURN, VALUE_EMPTY);
	AST* ret_expr = ParseExpression(parser);

	AddASTChild(node, ret_expr);

	return node;
}
Beispiel #10
0
AST* ParseArrayIndexing(ParserState* parser) {
	Value* id = Match(parser, TOKEN_ID);

	Match(parser, TOKEN_LEFT_SQUARE_BRACKET);
	AST* index = ParseExpression(parser);
	Match(parser, TOKEN_RIGHT_SQUARE_BRACKET);

	AST* ast = CreateASTNode(SEM_INDEX, id);
	AddASTChild(ast, index);

	return ast;
}
Beispiel #11
0
AST* ParseArray(ParserState* parser) {
	Match(parser, TOKEN_ARRAY);
	Match(parser, TOKEN_LEFT_SQUARE_BRACKET);

	AST* size_expr = ParseExpression(parser);

	Match(parser, TOKEN_RIGHT_SQUARE_BRACKET);

	AST* node = CreateASTNode(SEM_ARRAY, VALUE_EMPTY);
	AddASTChild(node, size_expr);

	return node;
}
Beispiel #12
0
AST* ParseExpression(ParserState* parser) {
	switch(parser->currentToken.type) {
		case TOKEN_INTREAD:
			Match(parser, TOKEN_INTREAD);
			return CreateASTNode(SEM_INTREAD, VALUE_EMPTY);
		case TOKEN_READ:
			Match(parser, TOKEN_READ);
			return CreateASTNode(SEM_READ, VALUE_EMPTY);
		case TOKEN_ARRAY:
			return ParseArray(parser);
		case TOKEN_OBJECT:
		case TOKEN_NEW:
			return ParseObject(parser);
		case TOKEN_FUNCTION:
			return ParseFunctionDefinition(parser);
		default:
			return ParseArithmeticalExpression(parser);
	}

	assert(0);
	return NULL;
}
Beispiel #13
0
AST* ParseFunctionCall(ParserState* parser) {
	Value* funcId = Match(parser, TOKEN_ID);

	AST* funcNode = CreateASTNode(SEM_FUNCCALL, funcId);

	Match(parser, TOKEN_LEFTBRACKET);
	AST* arglist = ParseArgumentList(parser);
	Match(parser, TOKEN_RIGHTBRACKET);

	AddASTChild(funcNode, arglist);

	return funcNode;
}
Beispiel #14
0
AST* ParseTerm(ParserState* parser) {
	AST* valueNode = ParseValue(parser);

	if(parser->currentToken.type == TOKEN_STAR) {
		Match(parser, TOKEN_STAR);

		AST* exprNode = CreateASTNode(SEM_MULTIPLICATION, VALUE_EMPTY);
		AddASTChild(exprNode, valueNode);
		AddASTChild(exprNode, ParseTerm(parser));

		return exprNode;
	} else if(parser->currentToken.type == TOKEN_SLASH) {
		Match(parser, TOKEN_SLASH);

		AST* exprNode = CreateASTNode(SEM_DIVISION, VALUE_EMPTY);
		AddASTChild(exprNode, valueNode);
		AddASTChild(exprNode, ParseTerm(parser));

		return exprNode;
	} else {
		return valueNode;
	}
}
Beispiel #15
0
AST* ParseArithmeticalExpression(ParserState* parser) {
	AST* termNode = ParseTerm(parser);

	if(parser->currentToken.type == TOKEN_PLUS) {
		Match(parser, TOKEN_PLUS);

		AST* exprNode = CreateASTNode(SEM_ADDITION, VALUE_EMPTY);
		AddASTChild(exprNode, termNode);
		AddASTChild(exprNode, ParseArithmeticalExpression(parser));

		return exprNode;
	} else if(parser->currentToken.type == TOKEN_MINUS) {
		Match(parser, TOKEN_MINUS);

		AST* exprNode = CreateASTNode(SEM_SUBTRACTION, VALUE_EMPTY);
		AddASTChild(exprNode, termNode);
		AddASTChild(exprNode, ParseArithmeticalExpression(parser));

		return exprNode;
	} else {
		return termNode;
	}
}
Beispiel #16
0
AST* ParseArgumentList(ParserState* parser) {
	AST* arglist = CreateASTNode(SEM_EMPTY, VALUE_EMPTY);	

	/* FIXME: At this time, ArgumentList is used both for calling
	 * and defining functions, which is wrong as it allows using
	 * constants as formal arguments of a function */
	while(parser->currentToken.type != TOKEN_RIGHTBRACKET) {
		AST* argument = ParseValue(parser);
		AddASTChild(arglist, argument);
		if(parser->currentToken.type != TOKEN_RIGHTBRACKET)
			Match(parser, TOKEN_COMMA);
	}

	return arglist;
}
Beispiel #17
0
AST* ParseWhileCycle(ParserState* parser) {
	Match(parser, TOKEN_WHILE);

	AST* whileNode = CreateASTNode(SEM_WHILE_CYCLE, VALUE_EMPTY);

	AST* condition = ParseCondition(parser);
	
	Match(parser, TOKEN_DO);

	AST* op = ParseOperator(parser);

	AddASTChild(whileNode, condition);
	AddASTChild(whileNode, op);

	return whileNode;
}
Beispiel #18
0
AST* ParseValue(ParserState* parser) {
	AST* node;
	if(parser->currentToken.type == TOKEN_NUMBER || parser->currentToken.type == TOKEN_STRING) {
		node =  CreateASTNode(SEM_CONSTANT, parser->currentToken.value);
		Match(parser, parser->currentToken.type);
	} else {
		if(parser->nextToken.type == TOKEN_LEFTBRACKET)
			return ParseFunctionCall(parser);

		Value *id = Match(parser, TOKEN_ID);

		/* XXX: Factor this out */
		if(parser->currentToken.type == TOKEN_LEFT_SQUARE_BRACKET) {
			Match(parser, TOKEN_LEFT_SQUARE_BRACKET);
			AST* size = ParseExpression(parser);
			Match(parser, TOKEN_RIGHT_SQUARE_BRACKET);

			node = CreateASTNode(SEM_INDEX,  id);
			AddASTChild(node, size);
		} else if(parser->currentToken.type == TOKEN_DOT) { 
			Match(parser, TOKEN_DOT);
			Value* field_name = Match(parser, TOKEN_FIELD);
			if(parser->currentToken.type == TOKEN_LEFTBRACKET) {
				node = CreateASTNode(SEM_METHOD_CALL, VALUE_EMPTY);

				AST* field_node = CreateASTNode(SEM_FIELD, id);
				AddASTChild(field_node, CreateASTNode(SEM_CONSTANT, field_name));

				AddASTChild(node, field_node);

				Match(parser, TOKEN_LEFTBRACKET);
				AddASTChild(node, ParseArgumentList(parser)); Match(parser, TOKEN_RIGHTBRACKET); } else {
				node = CreateASTNode(SEM_FIELD, id);
				AddASTChild(node, CreateASTNode(SEM_CONSTANT, field_name));
			}
		} else {
			node =  CreateASTNode(SEM_ID, id);
		}
	}

	return node;
}
Beispiel #19
0
AST* ParseFunctionDefinition(ParserState* parser) {
	Match(parser, TOKEN_FUNCTION);
	Value* name = NULL;
	if(parser->currentToken.type == TOKEN_ID) {
		name = Match(parser, TOKEN_ID);
	}

	AST* function = CreateASTNode(SEM_FUNCTION, name);

	Match(parser, TOKEN_LEFTBRACKET);
	AST* arglist = ParseArgumentList(parser);
	Match(parser, TOKEN_RIGHTBRACKET);

	AST* code = ParseBlock(parser);

	AddASTChild(function, arglist);
	AddASTChild(function, code);

	return function;
}
Beispiel #20
0
AST* ParseIfStatement(ParserState* parser) {
	Match(parser, TOKEN_IF);

	AST* ifNode = CreateASTNode(SEM_IF_STATEMENT, VALUE_EMPTY);

	AST* condition = ParseCondition(parser);

	Match(parser, TOKEN_THEN);

	AST* thenOp = ParseOperator(parser);

	AddASTChild(ifNode, condition);
	AddASTChild(ifNode, thenOp);

	if(parser->currentToken.type == TOKEN_ELSE) {
		Match(parser, TOKEN_ELSE);
		AST* elseOp = ParseOperator(parser);
		AddASTChild(ifNode, elseOp);
	}

	return ifNode;
}
Beispiel #21
0
AST* ParseLoad(ParserState* parser) {
	Match(parser, TOKEN_LOAD);
	return CreateASTNode(SEM_LOAD, Match(parser, TOKEN_STRING));
}
Beispiel #22
0
AST* ParseInclude(ParserState* parser) {
	Match(parser, TOKEN_INCLUDE);
	return CreateASTNode(SEM_INCLUDE, Match(parser, TOKEN_STRING));
}