92 lines
2.1 KiB
C
92 lines
2.1 KiB
C
/* This parsing library aims to imitate how Elm parses strings.
|
|
|
|
In contrast to Elm, however, this function makes use of the side-effects that
|
|
C brings, allowing for impurity and a lack of need to return values.
|
|
|
|
Instead, every parser merely returns a boolean that expresses whether it had
|
|
parsed successfully.
|
|
*/
|
|
|
|
#include <parse.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
const bool DEBUG = false;
|
|
|
|
/* Parse a single char and fetch the result.
|
|
*/
|
|
bool parse_char(char *text, int *cursor, char *c) {
|
|
int length = strlen(text);
|
|
|
|
if (DEBUG) printf("Parsing a char : ");
|
|
|
|
if (*cursor == length) {
|
|
if (DEBUG) printf("Reached end of string [FAIL]\n");
|
|
return false;
|
|
}
|
|
|
|
*c = text[*cursor];
|
|
*cursor = *cursor + 1;
|
|
if (DEBUG) printf("%c [Success]\n", *c);
|
|
return true;
|
|
}
|
|
|
|
/* Parse an integer.
|
|
*/
|
|
bool parse_int(char *text, int *cursor, int *output) {
|
|
int is_negative = parse_token(text, cursor, "-");
|
|
|
|
if (DEBUG) printf("Parsing int : ");
|
|
int answer = 0;
|
|
char c = text[*cursor];
|
|
|
|
if (c < '0' || c > '9') {
|
|
if (DEBUG) printf("%c [FAIL]\n", c);
|
|
return false;
|
|
}
|
|
|
|
do
|
|
{
|
|
if (DEBUG) printf("%c", c);
|
|
answer = (answer * 10) + (c - '0');
|
|
*cursor = *cursor + 1;
|
|
c = text[*cursor];
|
|
}
|
|
while (c >= '0' && c <= '9');
|
|
|
|
if (DEBUG) printf(" [Success ]\n");
|
|
|
|
if (is_negative) {
|
|
answer = -1 * answer;
|
|
}
|
|
|
|
*output = answer;
|
|
return true;
|
|
}
|
|
|
|
/* Parse a token of text.
|
|
*/
|
|
bool parse_token(char *text, int *cursor, char *token) {
|
|
int length = strlen(token), text_length = strlen(text);
|
|
if (DEBUG) printf("Parsing token \"%s\" : ", token);
|
|
|
|
if (text_length - *cursor < length) {
|
|
if (DEBUG) printf("Token too long, won't fit. [FAIL]\n");
|
|
return false;
|
|
}
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
if (DEBUG) printf("%c", text[*cursor + i]);
|
|
if (text[*cursor + i] != token[i]) {
|
|
if (DEBUG) printf(" [FAIL]\n");
|
|
*cursor = *cursor + i;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (DEBUG) printf(" [Success]\n");
|
|
*cursor = *cursor + length;
|
|
return true;
|
|
}
|