bool parse_PLAY(char * line, playTracePBN * playp) { #ifdef DEBUG printf("parse_PLAY: Got line '%s'\n", line); #endif int pos = 0; if (consume_tag(line, &pos, "PLAY") == false) return false; #ifdef DEBUG printf("parse_PLAY: Got tag 'PLAY', pos now %d\n", pos); #endif if (consume_int(line, &pos, &playp->number) == false) return false; #ifdef DEBUG printf("parse_PLAY: Read number %d\n", playp->number); #endif if (consume_string(line, &pos, playp->cards) == false) return false; #ifdef DEBUG printf("parse_PLAY: Read cards '%s'\n", playp->cards); #endif return true; }
bool parse_DEALERPAR(char * line, parResultsDealer * par) { #ifdef DEBUG printf("parse_DEALERPAR: Got line '%s'\n", line); #endif int pos = 0; if (consume_tag(line, &pos, "PAR2") == false) return false; #ifdef DEBUG printf("parse_DEALERPAR: Got tag 'PAR2'\n"); #endif char str[256]; if (consume_string(line, &pos, str) == false) return false; #ifdef DEBUG printf("parse_DEALERPAR: Read string '%s'\n", str); #endif if (sscanf(str, "%d", &par->score) != 1) return false; #ifdef DEBUG printf("parse_DEALERPAR: Read string '%s', number %d\n", str, par->score); #endif int no = 0; while (1) { if (consume_string(line, &pos, par->contracts[no]) == false) break; #ifdef DEBUG printf("parse_DEALERPAR: Read string number %d, '%s'\n", no, par->contracts[no]); #endif no++; } par->number = no; #ifdef DEBUG printf("parse_DEALERPAR: Read to number incl %d\n", no - 1); #endif return true; }
bool parse_PAR(char * line, parResults * par) { #ifdef DEBUG printf("parse_PAR: Got line '%s'\n", line); #endif int pos = 0; if (consume_tag(line, &pos, "PAR") == false) return false; #ifdef DEBUG printf("parse_PAR: Got tag 'PAR'\n"); #endif if (consume_string(line, &pos, par->parScore[0]) == false) return false; #ifdef DEBUG printf("parse_PAR: Read string '%s'\n", par->parScore[0]); #endif if (consume_string(line, &pos, par->parScore[1]) == false) return false; #ifdef DEBUG printf("parse_PAR: Read string '%s'\n", par->parScore[1]); #endif if (consume_string(line, &pos, par->parContractsString[0]) == false) return false; #ifdef DEBUG printf("parse_PAR: Read string '%s'\n", par->parContractsString[0]); #endif if (consume_string(line, &pos, par->parContractsString[1]) == false) return false; #ifdef DEBUG printf("parse_PAR: Read string '%s'\n", par->parContractsString[1]); #endif return true; }
bool parse_PBN( char * line, int * dealer, int * vul, dealPBN * dl) { #ifdef DEBUG printf("parse_PBN: Got line '%s'\n", line); #endif int pos = 0; if (consume_tag(line, &pos, "PBN") == false) return false; #ifdef DEBUG printf("parse_PBN: Got tag 'PBN'\n"); #endif if (consume_int(line, &pos, dealer) == false) return false; #ifdef DEBUG printf("parse_PBN: Read dealer %d\n", * dealer); #endif if (consume_int(line, &pos, vul) == false) return false; #ifdef DEBUG printf("parse_PBN: Read vul %d\n", * dealer); #endif if (consume_int(line, &pos, &dl->trump) == false) return false; #ifdef DEBUG printf("parse_PBN: Read trump %d\n", dl->trump); #endif if (consume_int(line, &pos, &dl->first) == false) return false; #ifdef DEBUG printf("parse_PBN: Read first %d\n", dl->first); #endif if (consume_string(line, &pos, dl->remainCards) == false) return false; #ifdef DEBUG printf("parse_PBN: Read string '%s'\n", dl->remainCards); #endif return true; }
static inline int lex_once(Lexer *lexer) { if (lexer->unscanned_dedents > 0) { lexer->unscanned_dedents--; return DEDENT; } else if (lexer->is_end) { return TOKEN_EOF; } else if (lexer->is_newline_phase) { lexer->is_newline_phase = 0; int next_indent_level = 0; int lookahead = Stream_peek(&lexer->stream); while (lookahead == ' ' || lookahead == '\n' || lookahead == '\t' || lookahead == '#') { Stream_pop(&lexer->stream); if (lookahead == '#') { int comment_c = Stream_peek(&lexer->stream); while (comment_c != '\n' && comment_c != CHAR_EOF) { Stream_pop(&lexer->stream); comment_c = Stream_peek(&lexer->stream); } } else if (lookahead == '\n') { next_indent_level = 0; } else { next_indent_level++; if (lexer->repr_indent_char == 0) { lexer->repr_indent_char = lookahead; } else if (lexer->repr_indent_char != lookahead) { error(lexer, LEXERR_MIXED_SPACES_AND_TABS, "Don't mix spaces and tabs to indicate indents"); return TOKEN_ERROR; } } lookahead = Stream_peek(&lexer->stream); } TEST_ERROR(lookahead); if (lookahead == CHAR_EOF) { flush_ind_stack(lexer); lexer->is_end = 1; Stream_clear_record(&lexer->stream); return lex_once(lexer); } int t = ind_stack_peek(lexer); if (ind_stack_empty(lexer)) { error(lexer, LEXERR_FATAL_ERROR, "FATAL INDENT ERROR"); return TOKEN_ERROR; } else if (t < next_indent_level) { ind_stack_push(lexer, next_indent_level); return INDENT; } else if (t > next_indent_level) { while (t > next_indent_level) { ind_stack_pop(lexer); t = ind_stack_peek(lexer); lexer->unscanned_dedents++; } if (t != next_indent_level) { error(lexer, LEXERR_INDENT_MISMATCH, "Indentation level mismatch"); return TOKEN_ERROR; } } Stream_clear_record(&lexer->stream); return lex_once(lexer); } int skip; int token; do { int c = Stream_pop(&lexer->stream); TEST_ERROR(c); token = 0; skip = 0; switch (c) { case CHAR_EOF: flush_ind_stack(lexer); if (lexer->bracket_depth > 0) { error(lexer, LEXERR_BRACKET_MISMATCH, "Expected closing bracket/parenthisis"); return TOKEN_ERROR; } else { token = NEWLINE; } lexer->is_end = 1; break; case ' ': case '\t': skip = 1; Stream_clear_record(&lexer->stream); break; case '\n': if (lexer->bracket_depth > 0) { skip = 1; Stream_clear_record(&lexer->stream); } else { token = NEWLINE; lexer->is_newline_phase = 1; } break; case '#': { int comment_c = Stream_peek(&lexer->stream); while (comment_c != '\n' && comment_c != CHAR_EOF) { Stream_pop(&lexer->stream); comment_c = Stream_peek(&lexer->stream); } skip = 1; Stream_clear_record(&lexer->stream); } break; #define NEWLINE_TOKEN_HACK(returned_token) {\ int col_c = Stream_peek(&lexer->stream); \ while (col_c == ' ' || col_c == '\t') { \ Stream_pop(&lexer->stream); \ col_c = Stream_peek(&lexer->stream); \ } \ if (col_c == '#' || col_c == '\n') { \ token = (returned_token); \ } \ } case '-': { int lookahead = Stream_peek(&lexer->stream); if (lookahead == '>') { Stream_pop(&lexer->stream); token = ARROW; } else if (lookahead == '-') { Stream_pop(&lexer->stream); NEWLINE_TOKEN_HACK(DMINUS_NEWLINE); if (token != DMINUS_NEWLINE) { error(lexer, LEXERR_INVALID_CHARACTER, "Expected newline after '--'"); return TOKEN_ERROR; } } else { token = MINUS; } break; } case ':': if (Stream_peek(&lexer->stream) == '=') { Stream_pop(&lexer->stream); token = DEFASSIGN; } else if (lexer->bracket_depth == 0) { NEWLINE_TOKEN_HACK(COLUMN_NEWLINE); if (token != COLUMN_NEWLINE) token = COLUMN; } else token = COLUMN; break; case '>': if (Stream_peek(&lexer->stream) == '=') { Stream_pop(&lexer->stream); token = GTE; } else if (lexer->bracket_depth == 0) { NEWLINE_TOKEN_HACK(GT_NEWLINE); if (token != GT_NEWLINE) token = GT; } else { token = GT; } break; case '<': if (Stream_peek(&lexer->stream) == '=') { Stream_pop(&lexer->stream); token = LTE; } else { token = LT; } break; case '.': if (Stream_peek(&lexer->stream) >= '0' && Stream_peek(&lexer->stream) <= '9') { while (Stream_peek(&lexer->stream) >= '0' && Stream_peek(&lexer->stream) <= '9') { Stream_pop(&lexer->stream); } token = FLOAT; } else { token = DOT; } break; case ',': token = COMMA; break; case '+': token = PLUS; break; case '/': token = SLASH; break; case '%': token = PERCENT; break; case '!': if (Stream_peek(&lexer->stream) == '=') { Stream_pop(&lexer->stream); token = NEQ; } else token = BANG; break; case '*': if (Stream_peek(&lexer->stream) == c) { Stream_pop(&lexer->stream); token = DSTAR; } else token = STAR; break; case '&': if (Stream_peek(&lexer->stream) == c) { Stream_pop(&lexer->stream); token = DAMP; } else token = AMP; break; case '|': if (Stream_peek(&lexer->stream) == c) { Stream_pop(&lexer->stream); token = DPIPE; } else token = PIPE; break; case '=': if (Stream_peek(&lexer->stream) == c) { Stream_pop(&lexer->stream); token = EQ; } else token = ASSIGN; break; case '\\': if (Stream_peek(&lexer->stream) == '\n' || Stream_peek(&lexer->stream) == CHAR_EOF) { Stream_pop(&lexer->stream); while (Stream_peek(&lexer->stream) == ' ' || Stream_peek(&lexer->stream) == '\t') { Stream_pop(&lexer->stream); } skip = 1; Stream_clear_record(&lexer->stream); } else { error(lexer, LEXERR_INVALID_AFTER_BACKSLASH, "Unexpected character after line continuation character"); return TOKEN_ERROR; } break; case '[': lexer->bracket_depth++; token = LBRKT; break; case '(': lexer->bracket_depth++; token = LPAR; break; case ']': if(lexer->bracket_depth == 0) { error(lexer, LEXERR_BRACKET_MISMATCH, "Openning bracket not found"); return TOKEN_ERROR; } lexer->bracket_depth--; token = RBRKT; break; case ')': if(lexer->bracket_depth == 0) { error(lexer, LEXERR_BRACKET_MISMATCH, "Openning parenthisis not found"); return TOKEN_ERROR; } lexer->bracket_depth--; token = RPAR; break; default: if (c >= '0' && c <= '9') { while (Stream_peek (&lexer->stream) >= '0' && Stream_peek (&lexer->stream) <= '9') { Stream_pop(&lexer->stream); } if (Stream_peek(&lexer->stream) != '.') { token = INTEGER; } else { Stream_pop(&lexer->stream); // consume dot while (Stream_peek (&lexer->stream) >= '0' && Stream_peek (&lexer->stream) <= '9') { Stream_pop(&lexer->stream); } token = FLOAT; } } else if (c == '\'' || c == '\"') { if (Stream_peek(&lexer->stream) == c) { Stream_pop(&lexer->stream); if (Stream_peek(&lexer->stream) == c) { Stream_pop(&lexer->stream); if (!consume_string(lexer, c, 1)) return TOKEN_ERROR; token = LONGSTRING; } else { // "" or '' token = STRING; } } else { if (!consume_string(lexer, c, 0)) return TOKEN_ERROR; token = STRING; } } else if (c == '$' || c == '@' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') { // letter [$@a-zA-Z_] // exletter [$@a-zA-Z0-9_!?] // pattern: {letter}{exletter}* char next = Stream_peek(&lexer->stream); while (next == '$' || next == '@' || (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z') || (next >= '0' && next <= '9') || next == '_' || next == '!' || next == '?') { Stream_pop(&lexer->stream); next = Stream_peek(&lexer->stream); } token = NAME; } else { char fmt[5]; char msg[128]; format_char(c, fmt); snprintf(msg, 128, "Invalid character: '%s' [line %d, col %d]", fmt, lexer->stream.curline, lexer->stream.curcol - 1); error(lexer, LEXERR_INVALID_CHARACTER, msg); return TOKEN_ERROR; } break; } } while (skip); return token; }