summaryrefslogtreecommitdiffstats
path: root/src/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp125
1 files changed, 120 insertions, 5 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index a1ee376..9d2fbce 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -36,6 +36,13 @@ enum parser_state {
STATE_RULE_BAR,
STATE_RULE_EQUAL,
STATE_RULE,
+ STATE_RULE_VAR_PRE,
+ STATE_RULE_VAR,
+ STATE_RULE_VAR_POST,
+ STATE_TYPE,
+ STATE_TYPE_NONTERM,
+ STATE_TYPE_TERM,
+ STATE_TYPE_TERM_BLOCK,
};
struct parser {
@@ -53,12 +60,16 @@ int parser_push(parser_t *parser, int token, const parser_value_t *value, parser
switch (parser->state) {
case STATE_INIT:
switch (token) {
- case TOK_NONTERM:
+ case TOK_SYMBOL_LC:
parser->state = STATE_RULE_BAR;
state->new_rule(value->str);
free(value->str);
return 1;
+ case TOK_TYPE:
+ parser->state = STATE_TYPE;
+ return 1;
+
case 0:
return 0;
}
@@ -83,12 +94,12 @@ int parser_push(parser_t *parser, int token, const parser_value_t *value, parser
case STATE_RULE:
switch (token) {
- case TOK_NONTERM:
+ case TOK_SYMBOL_LC:
state->add_rule_nonterminal(value->str);
free(value->str);
return 1;
- case TOK_TERM:
+ case TOK_SYMBOL_UC:
state->add_rule_terminal(value->str);
free(value->str);
return 1;
@@ -103,6 +114,10 @@ int parser_push(parser_t *parser, int token, const parser_value_t *value, parser
parser->state = STATE_INIT;
return 1;
+ case '(':
+ parser->state = STATE_RULE_VAR_PRE;
+ return 1;
+
case ';':
state->add_rule();
parser->state = STATE_INIT;
@@ -110,11 +125,111 @@ int parser_push(parser_t *parser, int token, const parser_value_t *value, parser
}
break;
+
+ case STATE_RULE_VAR_PRE:
+ switch (token) {
+ case TOK_SYMBOL:
+ case TOK_SYMBOL_UC:
+ case TOK_SYMBOL_LC:
+ state->add_rule_var(value->str);
+ free(value->str);
+ parser->state = STATE_RULE_VAR;
+ return 1;
+ }
+
+ break;
+
+ case STATE_RULE_VAR:
+ if (token == ')') {
+ parser->state = STATE_RULE;
+ return 1;
+ }
+
+ break;
+
+ case STATE_RULE_VAR_POST:
+ switch (token) {
+ case TOK_SYMBOL_LC:
+ state->add_rule_nonterminal(value->str);
+ free(value->str);
+ return 1;
+
+ case TOK_SYMBOL_UC:
+ state->add_rule_terminal(value->str);
+ free(value->str);
+ return 1;
+
+ case TOK_CHAR:
+ state->add_rule_terminal(value->number);
+ return 1;
+
+ case TOK_BLOCK:
+ state->add_rule(value->str);
+ free(value->str);
+ parser->state = STATE_INIT;
+ return 1;
+
+ case ';':
+ state->add_rule();
+ parser->state = STATE_INIT;
+ return 1;
+ }
+
+ break;
+
+ case STATE_TYPE:
+ switch (token) {
+ case TOK_SYMBOL_LC:
+ state->add_type_nonterminal(value->str);
+ free(value->str);
+ parser->state = STATE_TYPE_NONTERM;
+ return 1;
+
+ case TOK_SYMBOL_UC:
+ state->add_type_terminal(value->str);
+ free(value->str);
+ parser->state = STATE_TYPE_TERM;
+ return 1;
+ }
+
+ break;
+
+ case STATE_TYPE_NONTERM:
+ if (token == TOK_BLOCK) {
+ state->set_type_nonterminal(value->str);
+ free(value->str);
+ parser->state = STATE_INIT;
+ return 1;
+ }
+
+ break;
+
+ case STATE_TYPE_TERM:
+ if (token == TOK_BLOCK) {
+ state->set_type_terminal(value->str);
+ free(value->str);
+ parser->state = STATE_TYPE_TERM_BLOCK;
+ return 1;
+ }
+
+ break;
+
+ case STATE_TYPE_TERM_BLOCK:
+ switch (token) {
+ case TOK_SYMBOL:
+ case TOK_SYMBOL_UC:
+ case TOK_SYMBOL_LC:
+ state->set_type_terminal_name(value->str);
+ free(value->str);
+ parser->state = STATE_INIT;
+ return 1;
+ }
}
switch (token) {
- case TOK_NONTERM:
- case TOK_TERM:
+ case TOK_SYMBOL:
+ case TOK_SYMBOL_UC:
+ case TOK_SYMBOL_LC:
case TOK_CHAR:
case TOK_BLOCK:
free(value->str);;