Пример #1
0
bool  parserCls::factor(void)
{ EtokenType lTt1 = getTokenType();bool bb1 = true ;
  tokenContainCls lTc1 =getCurToken() ,lTc2;bool seeUnary= false;


  if( (lTt1 == Plus) || (lTt1==Minus) || (lTt1 == Not) )
  { if(lTt1== Plus)	 lTc1.type = UnaryPlus;
	 else if(lTt1== Minus) lTc1 . type = UnaryMinus;
	 lTc2=lTc1;getToken();lTt1=getTokenType();
	 lTc1=getCurToken();seeUnary=true;
  }
  switch(lTt1){
	 case OrdNumber:case SciNumber:case Array :
	addOperand() ;exprFound = true ;needOperand = false ;getToken();
	 break ;
	 case String :
		 if(seeUnary)
	 {errorUnary(lTc2 ,1);bb1 = false;break ;}
		 addOperand();exprFound=true;needOperand=false ;getToken();
	 break ;
	 case Name : exprFound = true ;needOperand=false;getToken();
	if(getTokenType() == Lparen ) bb1=addFunction(lTc1);
	else   addName(lTc1) ;
	 break ;
	 case Lparen :recursiveLparen() ;break ;
	 case Rparen :if(seeUnary)
		 {errorUnary(lTc2 , 2);bb1 = false ;break ;}
	 break ;
	 default :if(needOperand)	 errorFactor();
	  bb1 = false ;
	 break ;
  }
  if(seeUnary && bb1)	addOperator(lTc2);
  return bb1 ;
}
Пример #2
0
/// fa+b,c+d)
/// f is the name of function
// one error not checked f(a,,b)
bool parserCls::addFunction(tokenContainCls &lTc1)
{ lTc1.type = FunctionName; addOperand(lTc1);bool bb2 = true ;
  bool bb3=false;EtokenType  lt1;int iiExpr12=0,indexX=noTokenInExpr++;
  addOperand(lTc1); // for stack for change after end
 do{ if(bb3)	addOperand();
	  else 	 bb3 = true ;

	  getToken();// get next token after (
	  if(!term1() ){ bb2 = false   ;break ;}
	  if((noTokenInExpr-2) > (indexX))
			iiExpr12++;
	  lt1= getTokenType();
 }while((lt1==Comma));
 if(bb2) if(lt1 != Rparen)
	 {bb2 = false; errorRecursLparen(1, lTc1);}
 else {addOperator();getToken();}
 tokenContainCls lTc2(iiExpr12,1);
  addOperator(indexX, lTc2);
 return bb2 ;
}
Пример #3
0
bool  parserCls::factor(void)
{
  EtokenType lTt1 = getTokenType();
  bool bb1 = true ;
  tokenContainCls lTc1 =getCurToken();

  switch(lTt1)
  {
	 case OrdNumber:
	 case SciNumber:
	 case String :
	 case Array :
		  addOperand() ;

		  exprFound = true ;
		  needOperand = false ;
		noTokenInExpr++;

		  getToken();
	 break ;
	 case Name :

		 exprFound = true ;
		 needOperand = false ;
		 noTokenInExpr++;
		 getToken();
		 if(getTokenType() == Lparen )
			addFunction(lTc1);
		 else
			 addName(lTc1) ;
	 break ;
	 case Lparen :
		addOperator() ;
		recursiveLparen() ;
	 break ;
	 case Rparen :

	 break ;
	 default :
		if(needOperand)
			 errorFactor();
		 bb1 = false ;
	}
  return bb1 ;
}
Пример #4
0
/*
Function that lists and creates a cross reference table for the input file
and writes the result to the output file.

Works larkely like createCrossReferenceTable() but prints out the original line
with a line number if it is a valid mal statement. This only happens if there the
line starts with a comment, a label or if there exists an opcode.

It is assumed that the input file is a valid .mal file.

The function uses strtok to discern which section of the file it is in.
Based on this the function will either store an identifier - as a label or an operand,
or it will try and find a different operand, or do the same for a new line.

@inputFile The file to be read
@outputFile the output file to write the result
*/
void list_AND_CreateTable(FILE **inputFile, FILE **outputFile) {
	// Declares variable to store the line number
	int lineNumber;
	// Declares the head and the tail of the labelNode list, and current to move through it
	LABELNODE *head, *tail, *current;
	// Declares a current opNode to move through the list of occurances of an identifier
	OPNODE *currentOp;
	// Declares pointers to the original line read in, and a copy of it to be worked with
	char *line, *tempLine;
	// Allocates memory for the original line
	if( (line = (char *)malloc(LINE_LENGTH * sizeof(char))) == NULL) {
		// Prints error message if memory could not be alocated
		fprintf(stderr, "Could not allocate memory\n");
		// Exits the programme
		exit(1);
	}
	// Sets head and tail of labelNode list to NULL. The list is empty
	head = tail = NULL;
	// Sets the line number to be one
	lineNumber = 1;
	// Loop that all the lines from the input file. 
	while( fgets(line, LINE_LENGTH, *inputFile) != NULL) {
		// Initializes and resets tempLine to be NULL for further iterations
		tempLine = NULL;
		// Allocates memory for the temporary line
		if( (tempLine = (char *)malloc(LINE_LENGTH * sizeof(char))) == NULL) {
			// Prints error message if memory could not be alocated
			fprintf(stderr, "Could not allocate memory\n");
			// Exits the programme
			exit(1);
		}
		// Copies the original line into the temporary one
		strcpy(tempLine, line);
		// Cheks if the first char is a comment, and is to be ignored
		if(tempLine[0] == '#') {
			// Increments the line number after printing the original line with a line number
			fprintf(*outputFile, "#%d  %s", lineNumber++, line);
			// Starts the new iteration of the loop. Reads the next line from the file
			continue;
		}
		// Checks if the first char is a whitespace. No label is defined, but an opcode could occur
		else if(tempLine[0] == ' ' || tempLine[0] == '\t' || tempLine[0] == '\n') {
			// Remove whitespace to get to the opCode, or the end of the line.
			tempLine = strtok(tempLine, " \t");
		}// If not any of the above, there is a label to be defined
		else {
			// Tokenize the label by replacing the : delimenating the label
			tempLine = strtok(tempLine, ":");
			// The the label to the list
			addLabel(tempLine, lineNumber, &head, &tail);
			// Remove the white space between the label and the opCode
			tempLine = strtok(NULL, " \t");
		}

		// Checks if there is no opCode to be found
		if(tempLine == NULL || *tempLine == '\n') {
			// Prints the blank original line with no line number
			fprintf(*outputFile, "%s", line);
			// Starts the new iteration of the loop. Reads the next line from the file
			continue;
		}
		// If there was an opCode
		else if(tempLine != NULL || tempLine[0] != '\n') {
			// Writes the original line with a line number, because it has an opcode, and thus is a valid statement
			fprintf(*outputFile, "#%d  %s", lineNumber, line);
			// Ignore the opCode, by moving to the operand field of the line. Removes the white space before it.
			tempLine = strtok(NULL, " ,\t\n");

			// Checks if the current section is a comment. No operands were found
			if(tempLine != NULL && tempLine[0] == '#') {
				// Increment the line number
				lineNumber++;
				// Starts the new iteration of the loop. Reads the next line from the file
				continue;
			}
			// Checks if the line starts with a newline char
			else if(tempLine != NULL && tempLine[0] == '\n') {
				// Starts the new iteration of the loop. Reads the next line from the file
				continue;
			}
			// There are operands to check
			else {
				// Loop that goes through all the oprands by checking that the line does not start with # or \n.
				while(tempLine != NULL && *tempLine != '#' && *tempLine != '\n') {
					// Checks if the operand is a valid identifier
					if( isalpha(*tempLine) != 0 || *tempLine == '_') {
						// Add the identifier as an operand
						addOperand(tempLine, lineNumber, &head, &tail);
						// Set the line to start at the next operand, comment or end of the line
						tempLine = strtok(NULL, ", \t\n");
					}
					// Checks if the operand starts with a double or single quote
					else if(*tempLine == '\'' || *tempLine == '"') {
						// Stops the loop as there is nothing more to check for. No identifiers can occur at this point.
						break;
					}
					// If the operand is to be ignored
					else {
						// Move to the next operand, comment or end of the line.
						tempLine = strtok(NULL, " ,\t\n");
					}
				}
			}
			// Increments the line number
			lineNumber++;
		}
	}

	// *** Writes the result of the parsing to the output file. ***

	// Sets current to be head.
	current = head;
	// Sets currentOp to NULL.
	currentOp = NULL;
	// Writes the headers for the table
	fprintf(*outputFile, "\n   Cross Reference Table\n\n\tIdentifier \tDefinition \tUse\n\n");
	// Flushses the memory buffer
	fflush(*outputFile);
	// If there are no labels to create a table from
	if(head == NULL) {
		fprintf(*outputFile, "\t *** Table is empty ***\n");
		// Flushes the memory buffer
		fflush(*outputFile);
	}
	// If there are nodes to create a table from
	else {
		// Loop that goes through all the nodes in the list
		while(current != NULL) {
			if(strlen(current->identifier) > TAB) {
				fprintf(*outputFile, "\t %s \t %d   \t\t ", current->identifier, current->defined);
				// Flushes the memory buffer
				fflush(*outputFile);
			}
			else {
				fprintf(*outputFile, "\t %s \t\t %d   \t\t ", current->identifier, current->defined);
				// Flushes the memory buffer
				fflush(*outputFile);
			}
			// Sets the currentOp to be that of this labelNode's head
			currentOp = current->head;
			// Loop that goes through all the opNodes for this labelNode
			while(currentOp != NULL) {
				// Writes the line where the label was used
				fprintf(*outputFile, "%d  ", currentOp->used);
				// Flushes the memory buffer
				fflush(*outputFile);
				// Moves to the next node in the list
				currentOp = currentOp->next;
			}
			// Writes a newline char when the current label is done 
			fprintf(*outputFile, "\n");
			// Flushes the memory buffer
			fflush(*outputFile);
			// Moves to the next node
			current = current->next;
		}
	}
	// Closes the input file
	fclose(*inputFile);
	// Closes the output file
	fclose(*outputFile);
}
Пример #5
0
 void addOperand(const char* base, Args&&... args) {
   addOperand(std::make_shared<Translateable>(base, args...));
 }