1
0
Fork 0

multiple brackets

This commit is contained in:
Alex Kotov 2023-05-04 15:05:20 +04:00
parent cf870fdbc2
commit 27e35c826c
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
4 changed files with 165 additions and 53 deletions

40
enums.c
View file

@ -6,12 +6,16 @@
const char *State_to_str(const enum State state)
{
switch (state) {
case STATE_INIT: return "STATE_INIT";
case STATE_WHITESPACE: return "STATE_WHITESPACE";
case STATE_OPEN: return "STATE_OPEN";
case STATE_CLOSE: return "STATE_CLOSE";
case STATE_SYMBOL: return "STATE_SYMBOL";
case STATE_NUM: return "STATE_NUM";
case STATE_INIT: return "STATE_INIT";
case STATE_WHITESPACE: return "STATE_WHITESPACE";
case STATE_ROUND_OPEN: return "STATE_ROUND_OPEN";
case STATE_ROUND_CLOSE: return "STATE_ROUND_CLOSE";
case STATE_SQUARE_OPEN: return "STATE_SQUARE_OPEN";
case STATE_SQUARE_CLOSE: return "STATE_SQUARE_CLOSE";
case STATE_CURLY_OPEN: return "STATE_CURLY_OPEN";
case STATE_CURLY_CLOSE: return "STATE_CURLY_CLOSE";
case STATE_SYMBOL: return "STATE_SYMBOL";
case STATE_NUM: return "STATE_NUM";
}
return NULL;
}
@ -19,10 +23,14 @@ const char *State_to_str(const enum State state)
const char *TokenType_to_str(const enum TokenType token_type)
{
switch (token_type) {
case TOKEN_OPEN: return "TOKEN_OPEN";
case TOKEN_CLOSE: return "TOKEN_CLOSE";
case TOKEN_SYMBOL: return "TOKEN_SYMBOL";
case TOKEN_NUM: return "TOKEN_NUM";
case TOKEN_ROUND_OPEN: return "TOKEN_ROUND_OPEN";
case TOKEN_ROUND_CLOSE: return "TOKEN_ROUND_CLOSE";
case TOKEN_SQUARE_OPEN: return "TOKEN_SQUARE_OPEN";
case TOKEN_SQUARE_CLOSE: return "TOKEN_SQUARE_CLOSE";
case TOKEN_CURLY_OPEN: return "TOKEN_CURLY_OPEN";
case TOKEN_CURLY_CLOSE: return "TOKEN_CURLY_CLOSE";
case TOKEN_SYMBOL: return "TOKEN_SYMBOL";
case TOKEN_NUM: return "TOKEN_NUM";
}
return NULL;
}
@ -42,10 +50,14 @@ bool
State_to_token_type(const enum State state, enum TokenType *const token_type)
{
switch (state) {
case STATE_OPEN: *token_type = TOKEN_OPEN; break;
case STATE_CLOSE: *token_type = TOKEN_CLOSE; break;
case STATE_SYMBOL: *token_type = TOKEN_SYMBOL; break;
case STATE_NUM: *token_type = TOKEN_NUM; break;
case STATE_ROUND_OPEN: *token_type = TOKEN_ROUND_OPEN; break;
case STATE_ROUND_CLOSE: *token_type = TOKEN_ROUND_CLOSE; break;
case STATE_SQUARE_OPEN: *token_type = TOKEN_SQUARE_OPEN; break;
case STATE_SQUARE_CLOSE: *token_type = TOKEN_SQUARE_CLOSE; break;
case STATE_CURLY_OPEN: *token_type = TOKEN_CURLY_OPEN; break;
case STATE_CURLY_CLOSE: *token_type = TOKEN_CURLY_CLOSE; break;
case STATE_SYMBOL: *token_type = TOKEN_SYMBOL; break;
case STATE_NUM: *token_type = TOKEN_NUM; break;
default: return false;
}

16
enums.h
View file

@ -6,15 +6,23 @@
enum State {
STATE_INIT,
STATE_WHITESPACE,
STATE_OPEN,
STATE_CLOSE,
STATE_ROUND_OPEN,
STATE_ROUND_CLOSE,
STATE_SQUARE_OPEN,
STATE_SQUARE_CLOSE,
STATE_CURLY_OPEN,
STATE_CURLY_CLOSE,
STATE_SYMBOL,
STATE_NUM,
};
enum TokenType {
TOKEN_OPEN,
TOKEN_CLOSE,
TOKEN_ROUND_OPEN,
TOKEN_ROUND_CLOSE,
TOKEN_SQUARE_OPEN,
TOKEN_SQUARE_CLOSE,
TOKEN_CURLY_OPEN,
TOKEN_CURLY_CLOSE,
TOKEN_SYMBOL,
TOKEN_NUM,
};

125
lexer.c
View file

@ -42,10 +42,22 @@ void lex(const char chr)
switch (state) {
case STATE_INIT:
if (chr == '(') {
state = STATE_OPEN;
state = STATE_ROUND_OPEN;
buffer_add(chr);
} else if (chr == ')') {
state = STATE_CLOSE;
state = STATE_ROUND_CLOSE;
buffer_add(chr);
} else if (chr == '[') {
state = STATE_SQUARE_OPEN;
buffer_add(chr);
} else if (chr == ']') {
state = STATE_SQUARE_CLOSE;
buffer_add(chr);
} else if (chr == '{') {
state = STATE_CURLY_OPEN;
buffer_add(chr);
} else if (chr == '}') {
state = STATE_CURLY_CLOSE;
buffer_add(chr);
} else if (is_space(chr)) {
state = STATE_WHITESPACE;
@ -64,12 +76,32 @@ void lex(const char chr)
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
state = STATE_ROUND_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
state = STATE_ROUND_CLOSE;
buffer_add(chr);
} else if (chr == '[') {
token_add(state, buffer);
buffer_clean();
state = STATE_SQUARE_OPEN;
buffer_add(chr);
} else if (chr == ']') {
token_add(state, buffer);
buffer_clean();
state = STATE_SQUARE_CLOSE;
buffer_add(chr);
} else if (chr == '{') {
token_add(state, buffer);
buffer_clean();
state = STATE_CURLY_OPEN;
buffer_add(chr);
} else if (chr == '}') {
token_add(state, buffer);
buffer_clean();
state = STATE_CURLY_CLOSE;
buffer_add(chr);
} else if (is_space(chr)) {
buffer_add(chr);
@ -87,46 +119,41 @@ void lex(const char chr)
abort();
}
break;
case STATE_OPEN:
case STATE_ROUND_OPEN:
case STATE_ROUND_CLOSE:
case STATE_SQUARE_OPEN:
case STATE_SQUARE_CLOSE:
case STATE_CURLY_OPEN:
case STATE_CURLY_CLOSE:
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
state = STATE_ROUND_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
state = STATE_ROUND_CLOSE;
buffer_add(chr);
} else if (is_space(chr)) {
} else if (chr == '[') {
token_add(state, buffer);
buffer_clean();
state = STATE_WHITESPACE;
state = STATE_SQUARE_OPEN;
buffer_add(chr);
} else if (is_symbol_head(chr)) {
} else if (chr == ']') {
token_add(state, buffer);
buffer_clean();
state = STATE_SYMBOL;
state = STATE_SQUARE_CLOSE;
buffer_add(chr);
} else if (is_number(chr)) {
} else if (chr == '{') {
token_add(state, buffer);
buffer_clean();
state = STATE_NUM;
state = STATE_CURLY_OPEN;
buffer_add(chr);
} else {
abort();
}
break;
case STATE_CLOSE:
if (chr == '(') {
} else if (chr == '}') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
state = STATE_CURLY_CLOSE;
buffer_add(chr);
} else if (is_space(chr)) {
token_add(state, buffer);
@ -151,12 +178,32 @@ void lex(const char chr)
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
state = STATE_ROUND_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
state = STATE_ROUND_CLOSE;
buffer_add(chr);
} else if (chr == '[') {
token_add(state, buffer);
buffer_clean();
state = STATE_SQUARE_OPEN;
buffer_add(chr);
} else if (chr == ']') {
token_add(state, buffer);
buffer_clean();
state = STATE_SQUARE_CLOSE;
buffer_add(chr);
} else if (chr == '{') {
token_add(state, buffer);
buffer_clean();
state = STATE_CURLY_OPEN;
buffer_add(chr);
} else if (chr == '}') {
token_add(state, buffer);
buffer_clean();
state = STATE_CURLY_CLOSE;
buffer_add(chr);
} else if (is_space(chr)) {
token_add(state, buffer);
@ -173,12 +220,32 @@ void lex(const char chr)
if (chr == '(') {
token_add(state, buffer);
buffer_clean();
state = STATE_OPEN;
state = STATE_ROUND_OPEN;
buffer_add(chr);
} else if (chr == ')') {
token_add(state, buffer);
buffer_clean();
state = STATE_CLOSE;
state = STATE_ROUND_CLOSE;
buffer_add(chr);
} else if (chr == '[') {
token_add(state, buffer);
buffer_clean();
state = STATE_SQUARE_OPEN;
buffer_add(chr);
} else if (chr == ']') {
token_add(state, buffer);
buffer_clean();
state = STATE_SQUARE_CLOSE;
buffer_add(chr);
} else if (chr == '{') {
token_add(state, buffer);
buffer_clean();
state = STATE_CURLY_OPEN;
buffer_add(chr);
} else if (chr == '}') {
token_add(state, buffer);
buffer_clean();
state = STATE_CURLY_CLOSE;
buffer_add(chr);
} else if (is_space(chr)) {
token_add(state, buffer);

View file

@ -29,7 +29,10 @@ struct Object *expr()
assert(tokens_top());
switch (tokens_top()->type) {
case TOKEN_OPEN: return parens();
case TOKEN_ROUND_OPEN:
case TOKEN_SQUARE_OPEN:
case TOKEN_CURLY_OPEN:
return parens();
case TOKEN_SYMBOL:
{
struct Object *const object = Object_new_symbol(tokens_top()->val);
@ -51,22 +54,44 @@ struct Object *expr()
struct Object *parens()
{
expect(STATE_OPEN);
struct Object *const object = parens_part();
expect(STATE_CLOSE);
assert(tokens_top());
struct Object *object = NULL;
if (tokens_top()->type == TOKEN_ROUND_OPEN) {
expect(TOKEN_ROUND_OPEN);
object = parens_part();
expect(TOKEN_ROUND_CLOSE);
} else if (tokens_top()->type == TOKEN_SQUARE_OPEN) {
expect(TOKEN_SQUARE_OPEN);
object = parens_part();
expect(TOKEN_SQUARE_CLOSE);
} else {
expect(TOKEN_CURLY_OPEN);
object = parens_part();
expect(TOKEN_CURLY_CLOSE);
}
return object;
}
struct Object *parens_part()
{
assert(tokens_top());
if (tokens_top()->type == TOKEN_CLOSE) return NULL;
if (tokens_top()->type == TOKEN_ROUND_CLOSE ||
tokens_top()->type == TOKEN_SQUARE_CLOSE ||
tokens_top()->type == TOKEN_CURLY_CLOSE)
{
return NULL;
}
struct Object *const a = expr();
assert(tokens_top());
struct Object *b = NULL;
if (tokens_top()->type != TOKEN_CLOSE) {
if (tokens_top()->type != TOKEN_ROUND_CLOSE &&
tokens_top()->type != TOKEN_SQUARE_CLOSE &&
tokens_top()->type != TOKEN_CURLY_CLOSE)
{
b = parens_part();
}