Skip to content

Instantly share code, notes, and snippets.

@kspalaiologos
Created November 4, 2024 20:15
Show Gist options
  • Save kspalaiologos/d21678a5de2a698e1a393769afe082fc to your computer and use it in GitHub Desktop.
Save kspalaiologos/d21678a5de2a698e1a393769afe082fc to your computer and use it in GitHub Desktop.
Flex scanner for PGN files.
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
enum {
TAG = 0x100, COMMENT, REGULAR_MOVE, PROMOTION_MOVE, SHORT_CASTLE, LONG_CASTLE,
R1_0, R0_1, R12_12, RSTAR, CONTINUATION_MOVE_NUMBER, MOVE_NUMBER
};
%}
%option noyywrap
%option reentrant
%option nounput
%option noinput
NAG ("!!"|"??"|"!?"|"?!"|"!"|"?"|"="|("$"[0-9]{1,3}))
%%
"["[ \t]*[A-Za-z]+[ \t]+\"([^"]|\\\")*\"[ \t]*"]" { return TAG; }
("{"[^}]*"}")|(";"[^\n]*\n) { return COMMENT; }
[RNBKQ]?[a-h]?[1-8]?x?[a-h][1-8][+#]?{NAG}? { return REGULAR_MOVE; }
[a-h][1-8]=[RNBKQ][+#]?{NAG}? { return PROMOTION_MOVE; }
"O-O"{NAG}? { return SHORT_CASTLE; }
"O-O-O"{NAG}? { return LONG_CASTLE; }
"1-0" { return R1_0; }
"0-1" { return R0_1; }
"1/2-1/2" { return R12_12; }
"*" { return RSTAR; }
[0-9]+"..." { return CONTINUATION_MOVE_NUMBER; }
[0-9]+"." { return MOVE_NUMBER; }
[ \t\n\n\r\f\v]+ { /* ignore whitespace */ }
. { return yytext[0]; }
%%
int main(int argc, char * argv[]) {
yyscan_t scanner;
yylex_init(&scanner);
yyset_in(stdin, scanner);
int token;
while((token = yylex(scanner))) {
switch(token) {
case TAG:
printf("TAG: %s\n", yyget_text(scanner));
break;
case COMMENT:
printf("COMMENT: %s\n", yyget_text(scanner));
break;
case REGULAR_MOVE:
printf("REGULAR_MOVE: %s\n", yyget_text(scanner));
break;
case PROMOTION_MOVE:
printf("PROMOTION_MOVE: %s\n", yyget_text(scanner));
break;
case SHORT_CASTLE:
printf("SHORT_CASTLE\n");
break;
case LONG_CASTLE:
printf("LONG_CASTLE\n");
break;
case R1_0:
printf("R1_0\n");
break;
case R0_1:
printf("R0_1\n");
break;
case R12_12:
printf("R12_12\n");
break;
case RSTAR:
printf("RSTAR\n");
break;
case CONTINUATION_MOVE_NUMBER:
printf("CONTINUATION_MOVE_NUMBER: %s\n", yyget_text(scanner));
break;
case MOVE_NUMBER:
printf("MOVE_NUMBER: %s\n", yyget_text(scanner));
break;
default:
printf("UNKNOWN: %c\n", token);
}
}
yylex_destroy(scanner);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment