Finished the implemenation with Antigravity.
This commit is contained in:
@@ -1,6 +1,190 @@
|
||||
#include "../../Headers/slex_core.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static void print_usage(const char* prog_name) {
|
||||
printf("Usage: %s [options] <input_file> [options]\n\n", prog_name);
|
||||
printf("Options:\n");
|
||||
printf(" -o <output> Output file/output folder\n");
|
||||
printf(" -l <language> Specify target language: c, c#, csharp (default: detected or c)\n");
|
||||
printf(" -h <header> Output header file (separates declarations and implementation for C)\n");
|
||||
printf(" -ns <namespace> Specify namespace (C# only. Default: SLexGenerated)\n");
|
||||
printf(" -class <class_name> Specify class name (C# only. Default: SLexer)\n");
|
||||
printf(" -prefix <prefix> Specify prefix for functions/methods\n");
|
||||
printf(" -data_type <data_type> Specify data type name of the segment\n");
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
char* input_path = NULL;
|
||||
char* output_path = NULL;
|
||||
char* header_path = NULL;
|
||||
char* lang_str = NULL;
|
||||
char* ns_name = NULL;
|
||||
char* class_name = NULL;
|
||||
char* prefix = NULL;
|
||||
char* data_type_name = NULL;
|
||||
|
||||
for (int i = 1; i < ac; i++) {
|
||||
if (av[i][0] == '-') {
|
||||
if (strcmp(av[i], "-o") == 0) {
|
||||
if (i + 1 < ac) output_path = av[++i];
|
||||
else { fprintf(stderr, "Error: -o option requires an argument\n"); return 1; }
|
||||
} else if (strcmp(av[i], "-l") == 0) {
|
||||
if (i + 1 < ac) lang_str = av[++i];
|
||||
else { fprintf(stderr, "Error: -l option requires an argument\n"); return 1; }
|
||||
} else if (strcmp(av[i], "-h") == 0) {
|
||||
if (i + 1 < ac) header_path = av[++i];
|
||||
else { fprintf(stderr, "Error: -h option requires an argument\n"); return 1; }
|
||||
} else if (strcmp(av[i], "-ns") == 0) {
|
||||
if (i + 1 < ac) ns_name = av[++i];
|
||||
else { fprintf(stderr, "Error: -ns option requires an argument\n"); return 1; }
|
||||
} else if (strcmp(av[i], "-class") == 0) {
|
||||
if (i + 1 < ac) class_name = av[++i];
|
||||
else { fprintf(stderr, "Error: -class option requires an argument\n"); return 1; }
|
||||
} else if (strcmp(av[i], "-prefix") == 0) {
|
||||
if (i + 1 < ac) prefix = av[++i];
|
||||
else { fprintf(stderr, "Error: -prefix option requires an argument\n"); return 1; }
|
||||
} else if (strcmp(av[i], "-data_type") == 0) {
|
||||
if (i + 1 < ac) data_type_name = av[++i];
|
||||
else { fprintf(stderr, "Error: -data_type option requires an argument\n"); return 1; }
|
||||
} else {
|
||||
fprintf(stderr, "Error: Unknown option %s\n", av[i]);
|
||||
print_usage(av[0]);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (!input_path) {
|
||||
input_path = av[i];
|
||||
} else {
|
||||
fprintf(stderr, "Error: Multiple input files are not supported: %s\n", av[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!input_path) {
|
||||
fprintf(stderr, "Error: No input file specified\n");
|
||||
print_usage(av[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Determine target language
|
||||
slex_target_language target_lang = c_language;
|
||||
bool lang_detected = false;
|
||||
|
||||
if (lang_str) {
|
||||
char temp_lang[256];
|
||||
int l_len = (int)strlen(lang_str);
|
||||
for (int k = 0; k < l_len && k < 255; k++) {
|
||||
temp_lang[k] = (char)tolower((unsigned char)lang_str[k]);
|
||||
}
|
||||
temp_lang[l_len] = '\0';
|
||||
|
||||
if (strcmp(temp_lang, "c") == 0) {
|
||||
target_lang = c_language;
|
||||
lang_detected = true;
|
||||
} else if (strcmp(temp_lang, "c#") == 0 || strcmp(temp_lang, "csharp") == 0) {
|
||||
target_lang = csharp;
|
||||
lang_detected = true;
|
||||
} else {
|
||||
fprintf(stderr, "Error: Unsupported language %s\n", lang_str);
|
||||
return 1;
|
||||
}
|
||||
} else if (output_path) {
|
||||
// Guess language from output path extension
|
||||
char* ext = strrchr(output_path, '.');
|
||||
if (ext) {
|
||||
if (strcmp(ext, ".cs") == 0) {
|
||||
target_lang = csharp;
|
||||
lang_detected = true;
|
||||
} else if (strcmp(ext, ".c") == 0) {
|
||||
target_lang = c_language;
|
||||
lang_detected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lang_detected) {
|
||||
// Default to C if not specified and not detected
|
||||
target_lang = c_language;
|
||||
}
|
||||
|
||||
// Initialize options with defaults
|
||||
slex_options options;
|
||||
memset(&options, 0, sizeof(options));
|
||||
options.target_language = target_lang;
|
||||
options.header_output = header_path;
|
||||
|
||||
if (target_lang == c_language) {
|
||||
options.prefix = prefix ? prefix : "slex_";
|
||||
options.data_type_name = data_type_name ? data_type_name : "slex_segment";
|
||||
} else {
|
||||
options.namespace_name = ns_name ? ns_name : "SLexGenerated";
|
||||
options.class_name = class_name ? class_name : "SLexer";
|
||||
options.prefix = prefix ? prefix : "";
|
||||
options.data_type_name = data_type_name ? data_type_name : "Segment";
|
||||
}
|
||||
|
||||
// Load input rule file
|
||||
FILE* in_f = fopen(input_path, "r");
|
||||
if (!in_f) {
|
||||
fprintf(stderr, "Error: Failed to open input file %s\n", input_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
slex_rules rules;
|
||||
memset(&rules, 0, sizeof(rules));
|
||||
if (!slex_read_rule_from_file(in_f, &rules)) {
|
||||
fprintf(stderr, "Error: Failed to parse rule file %s\n", input_path);
|
||||
fclose(in_f);
|
||||
return 1;
|
||||
}
|
||||
fclose(in_f);
|
||||
|
||||
// Open output file
|
||||
FILE* out_f = stdout;
|
||||
if (output_path && strlen(output_path) > 0) {
|
||||
out_f = fopen(output_path, "w");
|
||||
if (!out_f) {
|
||||
fprintf(stderr, "Error: Failed to open output file %s\n", output_path);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform translation
|
||||
bool success = slex_translate_to_file(&options, &rules, out_f);
|
||||
|
||||
if (out_f != stdout) {
|
||||
fclose(out_f);
|
||||
}
|
||||
|
||||
// Free parsed rule structures
|
||||
for (uint64_t i = 0; i < rules.rule_count; i++) {
|
||||
free(rules.rules[i].Tag);
|
||||
free(rules.rules[i].Pattern);
|
||||
}
|
||||
free(rules.rules);
|
||||
|
||||
for (uint64_t i = 0; i < rules.mapping_count; i++) {
|
||||
free(rules.mappings[i].Id);
|
||||
free(rules.mappings[i].Tag);
|
||||
}
|
||||
free(rules.mappings);
|
||||
|
||||
for (uint64_t i = 0; i < rules.code_block_count; i++) {
|
||||
if (rules.code_blocks[i].post_processor_code) free(rules.code_blocks[i].post_processor_code);
|
||||
if (rules.code_blocks[i].variables) free(rules.code_blocks[i].variables);
|
||||
}
|
||||
free(rules.code_blocks);
|
||||
|
||||
if (!success) {
|
||||
fprintf(stderr, "Error: Code generation failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Success: Generated lexer source code\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user