#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_IDENTIFIER_SIZE 30
#define MAX_BUFFER_SIZE 100
// Token types
typedef enum {
TOKEN_IDENTIFIER,
TOKEN_INTEGER,
TOKEN_STRING,
TOKEN_OPERATOR,
TOKEN_KEYWORD,
TOKEN_END_OF_LINE,
TOKEN_COMMENT
} TokenType;
// Token structure
typedef struct {
TokenType type;
char lexeme[MAX_IDENTIFIER_SIZE + 1]; // +1 for null terminator
} Token;
// Global variables
int myInt;
char myText[MAX_BUFFER_SIZE];
// Function declarations
Token getNextToken(FILE* file);
void parseProgram(FILE* file);
void parseStatement(Token token, FILE* file);
void parseAssignment(Token token, FILE* file);
void parseFunctionCall(Token token, FILE* file);
void executeStatement(Token token);
void executeAssignment(Token token);
void executeFunctionCall(Token token);
void executeSize(Token token);
void executeSubs(Token token);
void executeLocate(Token token);
void executeInsert(Token token);
void executeOverride(Token token);
void executeAsString(Token token);
void executeAsText(Token token);
void executeRead(Token token);
void executeWrite(Token token);
void executeInput(Token token);
void executeOutput(Token token);
Token getNextToken(FILE* file) {
// Implement the lexer logic to read from the file and tokenize the input program
// Return the next token
Token token;
// Implement the lexer logic here
return token;
}
void parseProgram(FILE* file) {
Token token;
do {
token = getNextToken(file);
parseStatement(token, file);
} while (token.type != TOKEN_END_OF_LINE);
}
void parseStatement(Token token, FILE* file) {
if (token.type == TOKEN_IDENTIFIER) {
parseAssignment(token, file);
} else if (token.type == TOKEN_KEYWORD) {
parseFunctionCall(token, file);
}
}
void parseAssignment(Token token, FILE* file) {
// Implement the parsing logic for assignment statements
if (strcmp(token.lexeme, "new") != 0) {
printf("Error: Expected 'new' keyword.\n");
return;
}
Token nextToken = getNextToken(file);
if (nextToken.type != TOKEN_IDENTIFIER) {
printf("Error: Expected identifier after 'new'.\n");
return;
}
if (strcmp(nextToken.lexeme, "int") == 0) {
executeAssignment(token);
} else if (strcmp(nextToken.lexeme, "text") == 0) {
executeAssignment(token);
} else {
printf("Error: Invalid data type.\n");
return;
}
}
void parseFunctionCall(Token token, FILE* file) {
// Implement the parsing logic for function calls
// You will need to handle different predefined functions and their arguments
if (strcmp(token.lexeme, "size") == 0) {
executeSize(token);
} else if (strcmp(token.lexeme, "subs") == 0) {
executeSubs(token);
} else if (strcmp(token.lexeme, "locate") == 0) {
executeLocate(token);
} else if (strcmp(token.lexeme, "insert") == 0) {
executeInsert(token);
} else if (strcmp(token.lexeme, "override") == 0) {
executeOverride(token);
} else if (strcmp(token.lexeme, "asString") == 0) {
executeAsString(token);
} else if (strcmp(token.lexeme, "asText") == 0) {
executeAsText(token);
} else if (strcmp(token.lexeme, "read") == 0) {
executeRead(token);
} else if (strcmp(token.lexeme, "write") == 0) {
executeWrite(token);
} else if (strcmp(token.lexeme, "input") == 0) {
executeInput(token);
} else if (strcmp(token.lexeme, "output") == 0) {
executeOutput(token);
} else {
printf("Error: Invalid function call.\n");
return;
}
}
void executeStatement(Token token) {
// Implement the execution logic for statements
// You will need to determine the type of statement and call the appropriate execution function
switch (token.type) {
case TOKEN_IDENTIFIER:
executeAssignment(token);
break;
case TOKEN_KEYWORD:
executeFunctionCall(token);
break;
default:
// Invalid statement
printf("Invalid statement\n");
break;
}
void executeAssignment(Token token) {
// Extract the variable name and value from the token
char variable[MAX_IDENTIFIER_SIZE + 1];
char value[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%s :=", variable);
sscanf(token.lexeme, "%*s %*s %[^\n]", value);
// Update the variable value based on the right-hand side expression
// In this example, we assume the variable is a text type
if (strcmp(value, "input") == 0) {
// Handle input case separately
char inputBuffer[MAX_BUFFER_SIZE];
printf("Enter value for %s: ", variable);
fgets(inputBuffer, MAX_BUFFER_SIZE, stdin);
inputBuffer[strcspn(inputBuffer, "\n")] = '\0'; // Remove trailing newline character
// Update the variable with the input value
// TODO: Update the variable value based on your implementation
} else {
// Handle constant value assignment
// TODO: Update the variable value based on the constant value
}
}
void executeFunctionCall(Token token) {
// Extract the function name and arguments from the token
char function[MAX_IDENTIFIER_SIZE + 1];
char arguments[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%s %[^\n]", function, arguments);
// Handle different predefined functions and their execution
if (strcmp(function, "size") == 0) {
// Handle the size() function
// TODO: Extract the required argument(s) from the arguments string and perform the size() function logic
} else if (strcmp(function, "subs") == 0) {
// Handle the subs() function
// TODO: Extract the required argument(s) from the arguments string and perform the subs() function logic
} else if (strcmp(function, "locate") == 0) {
// Handle the locate() function
// TODO: Extract the required argument(s) from the arguments string and perform the locate() function logic
} else if (strcmp(function, "insert") == 0) {
// Handle the insert() function
// TODO: Extract the required argument(s) from the arguments string and perform the insert() function logic
} else if (strcmp(function, "override") == 0) {
// Handle the override() function
// TODO: Extract the required argument(s) from the arguments string and perform the override() function logic
} else if (strcmp(function, "asString") == 0) {
// Handle the asString() function
// TODO: Extract the required argument(s) from the arguments string and perform the asString() function logic
} else if (strcmp(function, "asText") == 0) {
// Handle the asText() function
// TODO: Extract the required argument(s) from the arguments string and perform the asText() function logic
} else {
// Handle unrecognized function calls
// TODO: Handle the case when the function is not recognized
}
}
void executeSize(Token token) {
// Extract the argument from the token
char argument[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %s", argument);
// Perform the size() function logic
// TODO: Extract the required variable from the argument and calculate its size
}
void executeSubs(Token token) {
// Extract the arguments from the token
char argument[MAX_BUFFER_SIZE];
int begin, end;
sscanf(token.lexeme, "%*s %[^,], %d, %d", argument, &begin, &end);
// Perform the subs() function logic
// TODO: Extract the required variables and perform the substring operation using begin and end values
}
void executeLocate(Token token) {
// Extract the arguments from the token
char bigText[MAX_BUFFER_SIZE];
char smallText[MAX_BUFFER_SIZE];
int start;
sscanf(token.lexeme, "%*s %[^,], %[^,], %d", bigText, smallText, &start);
// Perform the locate() function logic
// TODO: Extract the required variables and perform the locate operation using start value
}
void executeInsert(Token token) {
// Extract the arguments from the token
char myText[MAX_BUFFER_SIZE];
int location;
char insertText[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %[^,], %d, %[^,]", myText, &location, insertText);
// Perform the insert() function logic
// TODO: Extract the required variables and perform the insert operation at the specified location
}
void executeOverride(Token token) {
// Extract the arguments from the token
char myText[MAX_BUFFER_SIZE];
int location;
char ovrText[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %[^,], %d, %[^,]", myText, &location, ovrText);
// Perform the override() function logic
// TODO: Extract the required variables and perform the override operation at the specified location
}
void executeAsString(Token token) {
// Extract the argument from the token
int myInt;
sscanf(token.lexeme, "%*s %d", &myInt);
// Perform the asString() function logic
// TODO: Extract the required variable and perform the type conversion to string
}
void executeAsText(Token token) {
// Extract the argument from the token
char myString[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %[^;]", myString);
// Perform the asText() function logic
// TODO: Extract the required variable and perform the type conversion of myString to an integer
}
void executeRead(Token token) {
// Extract the arguments from the token
char myString[MAX_BUFFER_SIZE];
char filename[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %[^,], %[^\n]", myString, filename);
// Perform the read command logic
// TODO: Read a string from the specified file and assign it to myString
}
void executeWrite(Token token) {
// Extract the arguments from the token
char myText[MAX_BUFFER_SIZE];
char filename[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %[^,], %[^\n]", myText, filename);
// Perform the write command logic
// TODO: Write the string myText to the specified file
}
void executeInput(Token token) {
// Extract the arguments from the token
char myText[MAX_BUFFER_SIZE];
char promptText[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %[^,], %[^\n]", myText, promptText);
// Perform the input command logic
// TODO: Receive input from the user into myText using promptText as the prompt
}
void executeOutput(Token token) {
// Extract the argument from the token
char myText[MAX_BUFFER_SIZE];
sscanf(token.lexeme, "%*s %[^\n]", myText);
// Perform the output command logic
// TODO: Write myText to the screen or console
}
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Error: Invalid command line arguments.\n");
printf("Usage: TextJedi <filename>\n");
return 1;
}
FILE* file = fopen(argv[1], "r");
if (file == NULL) {
printf("Error: Failed to open file.\n");
return 1;
}
parseProgram(file);
fclose(file);
return 0;
}