Skip to content

Commit

Permalink
test: Add parser benchmarks.
Browse files Browse the repository at this point in the history
  • Loading branch information
xlauko committed Oct 1, 2024
1 parent 72c3063 commit 7ba7400
Show file tree
Hide file tree
Showing 9 changed files with 797 additions and 0 deletions.
100 changes: 100 additions & 0 deletions test/parsers/csv-a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// RUN: %vast-front -vast-emit-mlir=hl %s -o - | %file-check %s -check-prefix=HL

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINE_LEN 1024
#define MAX_FIELD_LEN 256

int parse_csv_line(char *line, char *fields[]);

// Non-parsing part: file handling and utility functions
// HL: hl.func @read_csv_file
void read_csv_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (!file) {
perror("Could not open file");
exit(EXIT_FAILURE);
}

char line[MAX_LINE_LEN];

// Parsing part: parsing lines and extracting fields
while (fgets(line, sizeof(line), file)) {
char *fields[MAX_FIELD_LEN];
int field_count = parse_csv_line(line, fields);

// Example use of parsed fields
printf("Parsed %d fields:\n", field_count);
for (int i = 0; i < field_count; ++i) {
printf("Field %d: %s\n", i, fields[i]);
}
printf("\n");

// Free the allocated memory for fields
for (int i = 0; i < field_count; ++i) {
free(fields[i]);
}
}

fclose(file);
}

// Parsing part: core CSV parsing logic
int parse_csv_line(char *line, char *fields[]) {
int count = 0;
char *start = line;
int in_quotes = 0;

while (*start) {
// Skip whitespace
while (*start == ' ' || *start == '\t') start++;

// Handle quotes
if (*start == '\"') {
in_quotes = 1;
start++;
}

// Capture the beginning of the field
char *field_start = start;

// Extract the field
while (*start && (in_quotes || (*start != ',' && *start != '\n'))) {
if (in_quotes && *start == '\"') {
if (*(start + 1) == '\"') {
start += 2; // Skip escaped quote
} else {
in_quotes = 0; // End of quoted field
start++;
break;
}
} else {
start++;
}
}

// Allocate memory for the field and store it
int length = start - field_start;
fields[count] = (char *)malloc(length + 1);
strncpy(fields[count], field_start, length);
fields[count][length] = '\0';
count++;

// Skip comma or newline
if (*start == ',') start++;
}

return count;
}

int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <csv-file>\n", argv[0]);
exit(EXIT_FAILURE);
}

read_csv_file(argv[1]);
return 0;
}
79 changes: 79 additions & 0 deletions test/parsers/csv-b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// RUN: %vast-front -vast-emit-mlir=hl %s -o - | %file-check %s -check-prefix=HL

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// Parsing part: A function to split a CSV line into tokens
// HL: hl.func @parse_csv_line
char **parse_csv_line(char *line, int *count) {
int capacity = 10; // Initial capacity for fields
char **fields = malloc(capacity * sizeof(char *));
*count = 0;

char *token = strtok(line, ",");
while (token != NULL) {
if (*count >= capacity) {
capacity *= 2;
fields = realloc(fields, capacity * sizeof(char *));
}
// Trim whitespace and add token to fields
fields[*count] = strdup(token);
(*count)++;

token = strtok(NULL, ",");
}
return fields;
}

// Non-parsing part: A function to handle the parsed CSV fields
// HL: hl.func @handle_csv_fields
void handle_csv_fields(char **fields, int count) {
printf("Parsed fields:\n");
for (int i = 0; i < count; ++i) {
printf("Field %d: %s\n", i + 1, fields[i]);
}
}

// Parsing part: Read the file line by line
void parse_csv_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
perror("Error opening file");
return;
}

char line[256];
while (fgets(line, sizeof(line), file)) {
// Remove newline character from the line
line[strcspn(line, "\n")] = '\0';

int count;
// Parse the line to extract CSV fields
char **fields = parse_csv_line(line, &count);

// Handle the parsed fields
handle_csv_fields(fields, count);

// Free allocated memory for fields
for (int i = 0; i < count; ++i) {
free(fields[i]);
}
free(fields);
}

fclose(file);
}

// Example usage
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return 1;
}

// Parsing part: Parse the CSV file
parse_csv_file(argv[1]);

return 0;
}
35 changes: 35 additions & 0 deletions test/parsers/expr-a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// RUN: %vast-front -vast-emit-mlir=hl %s -o - | %file-check %s -check-prefix=HL

#include <stdio.h>
#include <ctype.h>

// HL: hl.func @parse_number
int parse_number(const char **input) {
int value = 0;
while (isdigit(**input)) {
value = value * 10 + (**input - '0');
(*input)++;
}
return value;
}

// HL: hl.func @add_two_numbers
int add_two_numbers(const char *input) {
int num1 = parse_number(&input);
while (isspace(*input)) input++; // Skip spaces
input++; // Skip '+'
int num2 = parse_number(&input);
return num1 + num2;
}

int main() {
char input[100];

printf("Enter an expression (e.g., 3 + 5): ");
fgets(input, sizeof(input), stdin);

int result = add_two_numbers(input);
printf("Result: %d\n", result);

return 0;
}
93 changes: 93 additions & 0 deletions test/parsers/expr-b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// RUN: %vast-front -vast-emit-mlir=hl %s -o - | %file-check %s -check-prefix=HL

#include <stdio.h>
#include <ctype.h>

typedef enum { PLUS = '+', MINUS = '-', MUL = '*', DIV = '/', END = '\0' } TokenType;

typedef struct {
TokenType type;
int value;
} Token;

const char *input;

// HL: hl.func @get_next_token
Token get_next_token() {
while (isspace(*input)) input++; // Skip spaces

if (isdigit(*input)) {
int value = 0;
while (isdigit(*input)) {
value = value * 10 + (*input - '0');
input++;
}
return (Token){ .type = END, .value = value }; // Number token
} else if (*input == '+' || *input == '-' || *input == '*' || *input == '/') {
TokenType type = *input;
input++;
return (Token){ .type = type }; // Operator token
}

return (Token){ .type = END }; // End of input
}

int parse_factor(); // Forward declaration

// Parsing a term (factor possibly with '*' or '/')
int parse_term() {
int result = parse_factor();
Token token = get_next_token();

while (token.type == MUL || token.type == DIV) {
if (token.type == MUL) {
result *= parse_factor();
} else if (token.type == DIV) {
result /= parse_factor();
}
token = get_next_token();
}

return result;
}

// HL: hl.func @parse_factor
// Parsing a factor (number)
int parse_factor() {
Token token = get_next_token();
if (token.type == END) {
return token.value;
}
return 0; // Fallback
}

// HL: hl.func @parse_expression
// Parsing an expression (term possibly with '+' or '-')
int parse_expression() {
int result = parse_term();
Token token = get_next_token();

while (token.type == PLUS || token.type == MINUS) {
if (token.type == PLUS) {
result += parse_term();
} else if (token.type == MINUS) {
result -= parse_term();
}
token = get_next_token();
}

return result;
}

int main() {
char buffer[100];

printf("Enter an arithmetic expression (e.g., 3 + 5 * 2): ");
fgets(buffer, sizeof(buffer), stdin);

input = buffer;
int result = parse_expression();
printf("Result: %d\n", result);

return 0;
}
79 changes: 79 additions & 0 deletions test/parsers/img-a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// RUN: %vast-front -vast-emit-mlir=hl %s -o - | %file-check %s -check-prefix=HL

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

// Function to display the image as ASCII (for grayscale images)
// HL: hl.func @display_ascii_image
void display_ascii_image(uint8_t *pixel_data, uint16_t width, uint16_t height) {
printf("Displaying image as ASCII:\n");
for (uint16_t y = 0; y < height; ++y) {
for (uint16_t x = 0; x < width; ++x) {
// Map pixel values (0-255) to ASCII characters
uint8_t pixel = pixel_data[y * width + x];
char ascii_char = (pixel < 128) ? '#' : ' ';
printf("%c", ascii_char);
}
printf("\n");
}
}

// Function to parse a binary file containing a SIMPL image
// HL: hl.func @parse_simpl_image
void parse_simpl_image(const char *filename) {
FILE *file = fopen(filename, "rb");
if (!file) {
perror("Error opening file");
return;
}

// Read and validate the magic number (4 bytes)
char magic_number[5] = {0};
fread(magic_number, sizeof(char), 4, file);
if (strncmp(magic_number, "SIML", 4) != 0) {
printf("Invalid file format!\n");
fclose(file);
return;
}
printf("Valid SIMPL image format detected.\n");

// Read the width (2 bytes) and height (2 bytes)
uint16_t width, height;
fread(&width, sizeof(uint16_t), 1, file);
fread(&height, sizeof(uint16_t), 1, file);

// Read bits per pixel (1 byte)
uint8_t bpp;
fread(&bpp, sizeof(uint8_t), 1, file);

// Only support 8-bit grayscale images in this example
if (bpp != 8) {
printf("Unsupported bits per pixel: %u\n", bpp);
fclose(file);
return;
}

printf("Width: %u, Height: %u, Bits per Pixel: %u\n", width, height, bpp);

// Read pixel data (width * height bytes)
size_t pixel_data_size = width * height;
uint8_t *pixel_data = (uint8_t *)malloc(pixel_data_size);
fread(pixel_data, sizeof(uint8_t), pixel_data_size, file);

// Close the file
fclose(file);

// Display the image as ASCII (Non-Parsing Part)
display_ascii_image(pixel_data, width, height);

// Free memory
free(pixel_data);
}

int main() {
const char *filename = "image.simpl";
parse_simpl_image(filename);
return 0;
}
Loading

0 comments on commit 7ba7400

Please sign in to comment.