calc.cDenna kod är public domain. Om ni hittar fel eller vill ändra något i koden blir jag jätteglad om ni skickar dessa ändringar till jesper [at] fantasi [punkt] se.
/**
* En enkel parser för matematiska uttryck. Algoritmen är Recursive
* descent som är en av de flitigast använda i kompilatorer med mera.
* Denna version hanterar + - * / och ( ).
*/
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
/* Vi deklarerar funktionen här eftersom vi måste anropa den
* innan den definieras.
*/
static int readExpression(char** sr);
static int readNumber(char** sr)
{
int a = 0;
char next = *sr[0];
while (isdigit(next))
{
(*sr)++;
a = a * 10 + (int)(next - '0');
next = *sr[0];
}
return a;
}
static int readFactor(char** sr)
{
char next = *sr[0];
/* ( expr ) */
if (next == '(')
{
int a;
(*sr)++;
a = readExpression(sr);
next = *sr[0];
if (next != ')')
{
fprintf(stderr, "Syntax Error\n");
exit(EXIT_FAILURE);
}
(*sr)++;
return a;
}
/* - factor */
if (next == '-')
{
(*sr)++;
return -readFactor(sr);
}
/* number */
if (isdigit(next))
{
return readNumber(sr);
}
fprintf(stderr, "Syntax Error\n");
exit(EXIT_FAILURE);
}
static int readTerm(char** sr)
{
int a = readFactor(sr);
char next;
next = *sr[0];
while (next == '*' || next == '/')
{
(*sr)++;
if (next == '*')
a *= readFactor(sr);
else
a /= readFactor(sr);
next = *sr[0];
}
return a;
}
static int readExpression(char** sr)
{
int a = readTerm(sr);
char next;
next = *sr[0];
while (next == '+' || next == '-')
{
(*sr)++;
if (next == '+')
a += readTerm(sr);
else
a -= readTerm(sr);
next = *sr[0];
}
return a;
}
static void filter(char* something, char* result)
{
int i, j;
for (i = 0, j = 0; something[i] != '\0'; i++)
{
switch (something[i])
{
case ' ':
case '\t': break;
default: result[j++] = tolower(something[i]);
}
}
}
int main(int argc, char* argv[])
{
char* buffer;
char* filtered;
int a;
if (argc < 2)
{
printf("Usage: calc <expression>\n");
return EXIT_FAILURE;
}
buffer = filtered = malloc(strlen(argv[1]));
if (filtered == NULL)
{
printf("Out of memory\n");
return EXIT_FAILURE;
}
filter(argv[1], filtered);
a = readExpression(&filtered);
if (filtered[0] != '\0')
{
fprintf(stderr, "Syntax error\n");
free(buffer);
return EXIT_FAILURE;
}
else
printf("%d\n", a);
free(buffer);
return EXIT_SUCCESS;
}
|