Spaces:
Sleeping
Sleeping
| /* Trigo Game Notation Parser | |
| * Similar as PGN (Portable Game Notation) format | |
| */ | |
| /* ========== Lexical Grammar ========== */ | |
| %lex | |
| %% | |
| \s+ /* skip whitespace */ | |
| \n /* skip newlines */ | |
| ";"[^\n]* /* skip line comments */ | |
| "{"[^}]*"}" /* skip block comments */ | |
| /* Brackets */ | |
| "[" return '[' | |
| "]" return ']' | |
| /* String literals */ | |
| \"([^\\\"]|\\.)*\" return 'STRING' | |
| /* Tag names - Common PGN tags */ | |
| "Event" return 'TAG_EVENT' | |
| "Site" return 'TAG_SITE' | |
| "Date" return 'TAG_DATE' | |
| "Round" return 'TAG_ROUND' | |
| "Black" return 'TAG_BLACK' | |
| "White" return 'TAG_WHITE' | |
| "Result" return 'TAG_RESULT' | |
| /* Trigo-specific tags */ | |
| "Board" return 'TAG_BOARD' | |
| "Handicap" return 'TAG_HANDICAP' | |
| "Rules" return 'TAG_RULES' | |
| "TimeControl" return 'TAG_TIMECONTROL' | |
| "Annotator" return 'TAG_ANNOTATOR' | |
| "Application" return 'TAG_APPLICATION' | |
| /* Game result symbols */ | |
| "B+" return 'RESULT_BLACK' | |
| "W+" return 'RESULT_WHITE' | |
| "=" return '=' /* draw */ | |
| "*" return '*' /* unknown */ | |
| /* Move notation placeholders - will be expanded later */ | |
| [1-9][0-9]* return 'NUMBER' | |
| "." return 'DOT' | |
| "Pass" return 'PASS' | |
| "Resign" return 'RESIGN' | |
| "points" return 'POINTS' | |
| "stones" return 'STONES' | |
| [x](?=[1-9]) return 'TIMES' | |
| /* Coordinates for moves - will be refined */ | |
| [a-z0]+ return 'COORDINATE' | |
| /* Generic tag name for extensibility */ | |
| [A-Z][A-Za-z0-9_]* return 'TAG_NAME' | |
| /* End of file */ | |
| <<EOF>> return 'EOF' | |
| /* Catch-all for unexpected characters */ | |
| . return 'INVALID' | |
| /lex | |
| /* ========== Grammar Rules ========== */ | |
| %% | |
| game | |
| : tag_section move_section EOF | |
| { | |
| return { | |
| tags: $1, | |
| moves: $2, | |
| success: true | |
| }; | |
| } | |
| | tag_section EOF | |
| { | |
| return { | |
| tags: $1, | |
| moves: null, | |
| success: true | |
| }; | |
| } | |
| | move_section EOF | |
| { | |
| return { | |
| tags: {}, | |
| moves: $1, | |
| success: true | |
| }; | |
| } | |
| | EOF | |
| { | |
| return { | |
| tags: {}, | |
| moves: null, | |
| success: true | |
| }; | |
| } | |
| ; | |
| /* ========== Tag Section (Metadata) ========== */ | |
| tag_section | |
| : tag_pair -> $1 | |
| | tag_section tag_pair -> Object.assign({}, $1, $2) | |
| ; | |
| tag_pair | |
| : "[" tag_name STRING "]" | |
| { | |
| const tagName = $2; | |
| const tagValue = $3.slice(1, -1); // Remove quotes | |
| $$ = { [tagName]: tagValue }; | |
| } | |
| | "[" TAG_RESULT game_result "]" -> $3 | |
| | "[" TAG_BOARD board_shape "]" -> ({[$2]: $3}) | |
| ; | |
| tag_name | |
| : TAG_EVENT | |
| | TAG_SITE | |
| | TAG_DATE | |
| | TAG_ROUND | |
| | TAG_BLACK | |
| | TAG_WHITE | |
| | TAG_HANDICAP | |
| | TAG_RULES | |
| | TAG_TIMECONTROL | |
| | TAG_ANNOTATOR | |
| | TAG_APPLICATION | |
| | TAG_NAME { $$ = yytext; } | |
| ; | |
| /* ========== Movetext Section (Game Body) ========== */ | |
| /* PLACEHOLDER: Will be implemented in future iterations */ | |
| move_section | |
| : move_sequence | |
| //| move_sequence game_termination | |
| ; | |
| move_sequence | |
| : move_sequence_intact -> $1 | |
| | move_sequence_truncated -> $1 | |
| ; | |
| move_sequence_intact | |
| : /* empty */ -> [] | |
| | move_sequence_intact move_round -> $1.concat([$2]) | |
| ; | |
| move_sequence_truncated | |
| : move_sequence_intact move_round_half -> $1.concat([$2]) | |
| ; | |
| move_round | |
| : number DOT move_action move_action -> ({ round: $1, action_black: $3, action_white: $4 }) | |
| ; | |
| move_round_half | |
| : number DOT move_action -> ({ round: $1, action_black: $3 }) | |
| ; | |
| move_action | |
| : PASS -> ({ type: 'pass' }) | |
| | RESIGN -> ({ type: 'resign' }) | |
| | COORDINATE | |
| { | |
| // Placeholder: Parse coordinate notation | |
| $$ = { | |
| type: 'move', | |
| position: yytext | |
| }; | |
| } | |
| ; | |
| game_result | |
| : win -> ({Result: $1}) | |
| | win conquer -> ({Result: $1, Conquer: $2}) | |
| | "=" -> ({Result: "draw"}) | |
| | "*" -> ({Result: "unknown"}) | |
| ; | |
| win | |
| : RESULT_BLACK -> "black win" | |
| | RESULT_WHITE -> "white win" | |
| ; | |
| conquer | |
| : number conquer_unit -> ({n: $1, unit: $2}) | |
| ; | |
| conquer_unit | |
| : POINTS | |
| | STONES | |
| ; | |
| board_shape | |
| : number -> [$1] | |
| | board_shape TIMES number -> $1.concat($3) | |
| ; | |
| number | |
| : NUMBER -> parseInt($1) | |
| ; | |
| %% | |
| /* ========== Additional JavaScript Code ========== */ | |
| // Parser configuration | |
| parser.yy = { | |
| // Helper functions can be added here | |
| parseError: function(str, hash) { | |
| throw new Error('Parse error: ' + str); | |
| } | |
| }; | |