Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple parser benchmarks. #732

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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