logicparser/main.c
2024-09-18 11:48:00 +02:00

175 lines
2.9 KiB
C

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <math.h>
bool SolveFor(char* func, uint32_t vars, uint8_t* varMap)
{
char stack[1024];
int stackPtr;
int ptr;
bool valueA;
bool valueB;
stackPtr = 0;
ptr = 0;
while (func[ptr] != 0)
{
switch (func[ptr])
{
case '~':
{
assert(stackPtr > 0);
valueA = stack[stackPtr - 1];
stack[stackPtr-1] = !valueA;
break;
}
case '&':
{
assert(stackPtr > 1);
valueA = stack[--stackPtr];
valueB = stack[stackPtr-1];
stack[stackPtr - 1] = valueA && valueB;
break;
}
case '|':
{
assert(stackPtr > 1);
valueA = stack[--stackPtr];
valueB = stack[stackPtr-1];
stack[stackPtr - 1] = valueA || valueB;
break;
}
default:
{
if (func[ptr] == '0') stack[stackPtr++] = 0;
else if (func[ptr] == '1') stack[stackPtr++] = 1;
else if (func[ptr] >= 'a' && func[ptr] <= 'z')
{
assert(varMap[func[ptr] - 'a'] != 255);
stack[stackPtr++] = (vars >> varMap[func[ptr] - 'a']) & 0x01;
}
else assert(false);
break;
}
}
ptr++;
}
assert(stackPtr == 1);
return stack[stackPtr-1] != 0;
}
int main(int argc, char** argv)
{
char* formula = "p&q|a&b&~d&c|e&f|x&y|z|g&h&i&j";
int ptr;
char stack[1024];
char output[1024];
int stackPtr;
int outPtr;
int varCount;
uint8_t varMap[26];
ptr = 0;
stackPtr = 0;
outPtr = 0;
memset(varMap, 255, 26);
varCount = 0;
while(formula[ptr] != 0)
{
switch (formula[ptr])
{
case '~':
{
stack[stackPtr] = formula[ptr];
stackPtr++;
break;
}
case '&':
{
if (stackPtr > 0 && stack[stackPtr-1] == '~')
{
output[outPtr++] = stack[--stackPtr];
}
stack[stackPtr] = formula[ptr];
stackPtr++;
break;
}
case '|':
{
if (stackPtr > 0)
{
output[outPtr++] = stack[--stackPtr];
}
stack[stackPtr] = formula[ptr];
stackPtr++;
break;
}
default:
{
if (formula[ptr] >= 'a' && formula[ptr] <= 'z')
{
/** we got a variable **/
output[outPtr] = formula[ptr];
outPtr++;
if (varMap[formula[ptr] - 'a'] == 255)
varMap[formula[ptr] - 'a'] = varCount++;
}
else if (formula[ptr] == '0' || formula[ptr] == '1')
{
output[outPtr] = formula[ptr];
outPtr++;
}
else
{
printf("Unknown symbol %c!\n", formula[ptr]);
assert(false);
}
}
}
ptr++;
}
while (stackPtr > 0)
{
output[outPtr++] = stack[--stackPtr];
}
output[outPtr] = 0;
// print pretty header
for (int i = 0; i < 26; i++)
if (varMap[i] != 255)
printf("%c ", 'a'+i);
printf("Result\n");
// dirty hack
for (uint32_t i = 0; i < pow(2, varCount); i++)
{
// pretty printing
for (int j = 0; j < 26; j++)
if (varMap[j] != 255)
printf("%i ", (i >> varMap[j]) & 0x01);
printf("%i\n", SolveFor(output, i, varMap));
}
return 0;
}