static void next_token (scanner_t *scanner) { int start, end, type; char c; skip_spaces (scanner); start = scanner->idx; while (!is_eof (scanner) && !isspace (CUR_CHAR)) { if (scanner->idx == start) { if (is_special_char (CUR_CHAR)) { ++scanner->idx; break; } } else if (is_special_char (CUR_CHAR)) break; ++scanner->idx; } end = scanner->idx; c = scanner->input [start]; if (start >= scanner->size) type = TOKEN_EOF; else if (isdigit (c) || c == '\'') type = TOKEN_NUM; else if (ispunct_char (c)) type = TOKEN_PUNC; else type = TOKEN_ID; scanner->current.start = start; scanner->current.end = end; scanner->current.type = type; scanner->current.line = scanner->line; DEBUG_SCANNER (dump_token (scanner, &scanner->current)); }
//字句解析結果のリストを表示する void dump_token_list_data(list_node *token_list_head){ list_node *currentNode = token_list_head->next; while (currentNode) { dump_token((token *)(currentNode->data)); currentNode = currentNode->next; } }
static TOKEN emit(LEXER *l) { TOKEN t; while (l->f) { t = l->f(l); if (t.type == T_RESTART) { continue; } dump_token(&t); return t; } }
static int parse_top(PARSER *p) { TOKEN t1, t2; char *s; int i; t1 = emit(p->l); switch (t1.type) { case T_KEYWORD_LISTEN: case T_KEYWORD_MONITOR: case T_KEYWORD_HBA: case T_KEYWORD_USER: case T_KEYWORD_GROUP: case T_KEYWORD_PIDFILE: case T_KEYWORD_AUTHDB: t2 = emit(p->l); s = as_string(&t2); if (!s) { return -1; } switch (t1.type) { case T_KEYWORD_LISTEN: set_str(&p->listen, s); free(s); break; case T_KEYWORD_MONITOR: set_str(&p->monitor, s); free(s); break; case T_KEYWORD_HBA: set_str(&p->hbafile, s); free(s); break; case T_KEYWORD_USER: set_str(&p->user, s); free(s); break; case T_KEYWORD_GROUP: set_str(&p->group, s); free(s); break; case T_KEYWORD_PIDFILE: set_str(&p->pidfile, s); free(s); break; case T_KEYWORD_AUTHDB: set_str(&p->authdb, s); free(s); break; } return 0; case T_KEYWORD_LOG: t2 = emit(p->l); switch (t2.type) { case T_KEYWORD_ERROR: set_int(&p->loglevel, LOG_ERR); break; case T_KEYWORD_INFO: set_int(&p->loglevel, LOG_INFO); break; case T_KEYWORD_DEBUG: set_int(&p->loglevel, LOG_DEBUG); break; default: printf("bad log level\n"); return 1; } return 0; case T_KEYWORD_WORKERS: t2 = emit(p->l); switch (t2.type) { case T_TYPE_INTEGER: case T_TYPE_TIME: case T_TYPE_SIZE: i = t2.semval.i; break; default: dump_token(&t2); printf("unexpected token\n"); return 1; } if (i < 1) { printf("invalid number of workers (%d)!\n", i); return 1; } set_int(&p->workers, i); return 0; case T_KEYWORD_TLS: t2 = emit(p->l); if (t2.type != T_OPEN) { printf("bad follow-on to tls\n"); return -1; } p->f = parse_tls; return 0; case T_KEYWORD_HEALTH: t2 = emit(p->l); if (t2.type != T_OPEN) { printf("bad follow-on to health\n"); return -1; } p->f = parse_health; return 0; case T_KEYWORD_BACKEND: t2 = emit(p->l); if (t2.type == T_KEYWORD_DEFAULT) { p->current = backend(p, NULL); } else { s = as_string(&t2); if (!s) { printf("bad backend scope!\n"); return -1; } p->current = backend(p, s); free(s); } if (!p->current) { return -1; } t2 = emit(p->l); if (t2.type != T_OPEN) { printf("bad follow-on to backend\n"); return -1; } p->f = parse_backend; return 0; case T_EOS: p->f = NULL; return 0; default: fprintf(stderr, "bad toplevel\n"); p->f = NULL; return 1; } }