multiple brackets
This commit is contained in:
parent
cf870fdbc2
commit
27e35c826c
4 changed files with 165 additions and 53 deletions
40
enums.c
40
enums.c
|
@ -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
16
enums.h
|
@ -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
125
lexer.c
|
@ -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);
|
||||
|
|
37
parser.c
37
parser.c
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue