112 lines
4.0 KiB
C
112 lines
4.0 KiB
C
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include "slex.h"
|
||
|
|
#include "scc.h"
|
||
|
|
static double evaluate(scc_syntax_node* node) {
|
||
|
|
if (!node) return 0.0;
|
||
|
|
|
||
|
|
switch (node->id) {
|
||
|
|
case scc_id_number_expr: {
|
||
|
|
if (node->child_count > 0 && node->children[0].type == scc_segment) {
|
||
|
|
slex_segment* seg = (slex_segment*)node->children[0].data;
|
||
|
|
return atof(seg->head);
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
case scc_id_group_expr: {
|
||
|
|
if (node->child_count > 0 && node->children[0].type == scc_node) {
|
||
|
|
return evaluate((scc_syntax_node*)node->children[0].data);
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
case scc_id_term:
|
||
|
|
case scc_id_expr: {
|
||
|
|
if (node->child_count > 0 && node->children[0].type == scc_node) {
|
||
|
|
return evaluate((scc_syntax_node*)node->children[0].data);
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
case scc_id_add_expr: {
|
||
|
|
if (node->child_count == 3 && node->children[0].type == scc_node && node->children[2].type == scc_node) {
|
||
|
|
return evaluate((scc_syntax_node*)node->children[0].data) + evaluate((scc_syntax_node*)node->children[2].data);
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
case scc_id_sub_expr: {
|
||
|
|
if (node->child_count == 3 && node->children[0].type == scc_node && node->children[2].type == scc_node) {
|
||
|
|
return evaluate((scc_syntax_node*)node->children[0].data) - evaluate((scc_syntax_node*)node->children[2].data);
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
case scc_id_mul_expr: {
|
||
|
|
if (node->child_count == 3 && node->children[0].type == scc_node && node->children[2].type == scc_node) {
|
||
|
|
return evaluate((scc_syntax_node*)node->children[0].data) * evaluate((scc_syntax_node*)node->children[2].data);
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
case scc_id_div_expr: {
|
||
|
|
if (node->child_count == 3 && node->children[0].type == scc_node && node->children[2].type == scc_node) {
|
||
|
|
double divisor = evaluate((scc_syntax_node*)node->children[2].data);
|
||
|
|
if (divisor == 0.0) {
|
||
|
|
fprintf(stderr, "Error: Division by zero!\n");
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
return evaluate((scc_syntax_node*)node->children[0].data) / divisor;
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
default:
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void print_ast(scc_syntax_node* node, int indent) {
|
||
|
|
if (!node) return;
|
||
|
|
for (int i = 0; i < indent; i++) printf(" ");
|
||
|
|
printf("Node: %s (id=%d, child_count=%lld)\n", node->syntax_name, node->id, (long long)node->child_count);
|
||
|
|
for (uint64_t i = 0; i < node->child_count; i++) {
|
||
|
|
scc_syntax_node_enclosure* child = &node->children[i];
|
||
|
|
if (child->type == scc_node) {
|
||
|
|
print_ast((scc_syntax_node*)child->data, indent + 1);
|
||
|
|
} else {
|
||
|
|
slex_segment* seg = (slex_segment*)child->data;
|
||
|
|
for (int j = 0; j < indent + 1; j++) printf(" ");
|
||
|
|
printf("Segment: '%s' (tag=%d, id=%d)\n", seg->head, seg->tag, seg->id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(int ac, char** av) {
|
||
|
|
char* input_expr = "3 + 4 * ( 5 - 2 )";
|
||
|
|
if(ac==2){
|
||
|
|
input_expr=av[1];
|
||
|
|
}
|
||
|
|
printf("Lexing input expression: \"%s\"\n", input_expr);
|
||
|
|
|
||
|
|
slex_segment* lexer_head = NULL;
|
||
|
|
if (!slex_cstr((char*)input_expr, "input", &lexer_head)) {
|
||
|
|
fprintf(stderr, "Error: Lexical analysis failed\n");
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("Parsing lexical segments...\n");
|
||
|
|
scc_syntax_node* root = NULL;
|
||
|
|
if (!scc_parse(lexer_head, &root)) {
|
||
|
|
fprintf(stderr, "Error: Parsing failed\n");
|
||
|
|
slex_free(lexer_head);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("\nAST Structure:\n");
|
||
|
|
print_ast(root, 0);
|
||
|
|
|
||
|
|
double result = evaluate(root);
|
||
|
|
printf("\nEvaluation Result:\n");
|
||
|
|
printf("%s = %g\n", input_expr, result);
|
||
|
|
|
||
|
|
scc_free(root);
|
||
|
|
slex_free(lexer_head);
|
||
|
|
return 0;
|
||
|
|
}
|