215 lines
6.1 KiB
Plaintext
215 lines
6.1 KiB
Plaintext
grammar SGF;
|
|
|
|
@header {package net.woodyfolsom.msproj.sgf;}
|
|
|
|
@lexer::header {package net.woodyfolsom.msproj.sgf;}
|
|
|
|
collection returns [SGFNodeCollection sgfNodeCollection]
|
|
@init {
|
|
$sgfNodeCollection = new SGFNodeCollection();
|
|
}
|
|
: (gameTree{$sgfNodeCollection.add($gameTree.sgfGameTree);})+
|
|
;
|
|
|
|
gameTree returns [SGFGameTree sgfGameTree]
|
|
@init {
|
|
$sgfGameTree = new SGFGameTree();
|
|
}
|
|
: LPAREN sequence{$sgfGameTree.setNodeSequence($sequence.nodeSequence);} (gameTree{$sgfGameTree.addSubTree(sgfGameTree);})* RPAREN
|
|
;
|
|
|
|
sequence returns [List<SGFNode> nodeSequence]
|
|
@init {
|
|
$nodeSequence = new ArrayList<SGFNode>();
|
|
}
|
|
: (node{$nodeSequence.add($node.sgfNode);})+;
|
|
|
|
node returns [SGFNode sgfNode]
|
|
@init {
|
|
$sgfNode = new SGFNode();
|
|
}
|
|
: SEMICOLON (property{$sgfNode.addProperty($property.sgfProperty);})*;
|
|
|
|
property returns [SGFProperty sgfProperty]
|
|
@init {
|
|
$sgfProperty = new SGFProperty();
|
|
}
|
|
: (numIdent{$sgfProperty.setIdentifier($numIdent.sgfIdent);}) ((LBRACKET numValue RBRACKET){$sgfProperty.addValue($numValue.sgfValue);})+
|
|
|
|
//an empty coord is a pass move
|
|
| (playerIdent{$sgfProperty.setIdentifier($playerIdent.sgfPlayer);}) ((LBRACKET RBRACKET){sgfProperty.addValue(SGFValue.EMPTY);})+
|
|
| (playerIdent{$sgfProperty.setIdentifier($playerIdent.sgfPlayer);}) ((LBRACKET coordValue RBRACKET){sgfProperty.addValue(new SGFValue<SGFCoord>($coordValue.sgfCoord));})+
|
|
|
|
// 2 rules here because the disambiguating semantic pred. for 'player' would throw NPE
|
|
| (strIdent{$sgfProperty.setIdentifier($strIdent.sgfIdent);}) ((LBRACKET RBRACKET){$sgfProperty.addValue(SGFValue.EMPTY);})
|
|
| (strIdent{$sgfProperty.setIdentifier($strIdent.sgfIdent);}) ((LBRACKET strValue RBRACKET){$sgfProperty.addValue(new SGFValue<String>($strValue.text));})+
|
|
|
|
| (result{$sgfProperty.setIdentifier(SGFIdentifier.RESULT);}) ((LBRACKET strValue RBRACKET){$sgfProperty.addValue(new SGFValue<SGFResult>(new SGFResult($strValue.text)));})+
|
|
|
|
| (komi{$sgfProperty.setIdentifier(SGFIdentifier.KOMI);}) ((LBRACKET realValue RBRACKET){$sgfProperty.addValue(new SGFValue<Double>(Double.parseDouble($realValue.text)));})+
|
|
| (coordIdent{$sgfProperty.setIdentifier($coordIdent.sgfIdent);})((LBRACKET coordValue RBRACKET){$sgfProperty.addValue(new SGFValue<SGFCoord>(new SGFCoord($coordValue.text)));})+
|
|
;
|
|
|
|
//playerIdent is a disambiguating rule
|
|
playerIdent returns [SGFIdentifier sgfPlayer]
|
|
: {(input.LT(1).getText().equals("W"))}? strIdent {$sgfPlayer = $strIdent.sgfIdent;}
|
|
| {(input.LT(1).getText().equals("B"))}? strIdent {$sgfPlayer = $strIdent.sgfIdent;}
|
|
| {(input.LT(1).getText().equals("White"))}? strIdent {$sgfPlayer = $strIdent.sgfIdent;}
|
|
| {(input.LT(1).getText().equals("Black"))}? strIdent {$sgfPlayer = $strIdent.sgfIdent;}
|
|
;
|
|
|
|
strIdent returns [SGFIdentifier sgfIdent]
|
|
: charEnc{$sgfIdent = SGFIdentifier.CHARSET;}
|
|
| source{$sgfIdent = SGFIdentifier.SOURCE;}
|
|
| blackCountry{$sgfIdent = SGFIdentifier.COUNTRY_BLACK;}
|
|
| whiteCountry{$sgfIdent = SGFIdentifier.COUNTRY_WHITE;}
|
|
| event{$sgfIdent = SGFIdentifier.EVENT;}
|
|
| playerBlack{$sgfIdent = SGFIdentifier.PLAYER_BLACK;}
|
|
| playerWhite{$sgfIdent = SGFIdentifier.PLAYER_WHITE;}
|
|
| blackRank{$sgfIdent = SGFIdentifier.RANK_BLACK;}
|
|
| whiteRank{$sgfIdent = SGFIdentifier.RANK_WHITE;}
|
|
| rules{$sgfIdent = SGFIdentifier.RULES;}
|
|
| place{$sgfIdent = SGFIdentifier.PLACE;}
|
|
| application{$sgfIdent = SGFIdentifier.APPLICATION;}
|
|
| copyright
|
|
| username
|
|
| date{$sgfIdent = SGFIdentifier.DATE;}
|
|
| 'Black'{$sgfIdent = SGFIdentifier.MOVE_BLACK;}
|
|
| 'White'{$sgfIdent = SGFIdentifier.MOVE_WHITE;}
|
|
| 'B'{$sgfIdent = SGFIdentifier.MOVE_BLACK;}
|
|
| 'W'{$sgfIdent = SGFIdentifier.MOVE_WHITE;}
|
|
| view{$sgfIdent = SGFIdentifier.VIEW;} //this is not really a strIdent, but is a placeholder since I don't use this info
|
|
| comment{$sgfIdent = SGFIdentifier.COMMENT;}
|
|
//SGF grammar proper allows extensions, but this reader does not
|
|
; //if this is matched from rule playerIdent, the value is thrown away - this rule alone
|
|
//lack the context to disambiguate the single-character player movement IDs.
|
|
|
|
coordIdent returns [SGFIdentifier sgfIdent]
|
|
: addBlack{$sgfIdent = $addBlack.sgfIdent;}
|
|
| addWhite{$sgfIdent = $addWhite.sgfIdent;}
|
|
;
|
|
|
|
numIdent returns [SGFIdentifier sgfIdent]
|
|
: fileFormat{$sgfIdent = SGFIdentifier.FILE_FORMAT;}
|
|
| game{$sgfIdent = SGFIdentifier.GAME;}
|
|
| size{$sgfIdent = SGFIdentifier.SIZE;}
|
|
| time{$sgfIdent = SGFIdentifier.TIME;};
|
|
|
|
numValue returns [SGFValue<Integer> sgfValue]
|
|
: (STRVALUE){$sgfValue = new SGFValue<Integer>(Integer.parseInt($numValue.text));};
|
|
|
|
realIdent
|
|
: komi;
|
|
|
|
realValue
|
|
: STRVALUE;
|
|
|
|
coordValue returns [SGFCoord sgfCoord]
|
|
: STRVALUE {$sgfCoord = new SGFCoord($coordValue.text);}
|
|
;
|
|
|
|
fileFormat
|
|
: 'FF';
|
|
|
|
game : 'GM' | 'GaMe';
|
|
|
|
size : 'SZ' | 'SiZe';
|
|
|
|
view : 'VW' | 'VieW';
|
|
|
|
charEnc : 'CA';
|
|
|
|
source : 'SO';
|
|
|
|
blackCountry
|
|
: 'BC';
|
|
|
|
whiteCountry
|
|
: 'WC';
|
|
|
|
event : 'EV' | 'EVent';
|
|
|
|
playerBlack
|
|
: 'PB' | 'PlayerBlack';
|
|
playerWhite
|
|
: 'PW' | 'PlayerWhite';
|
|
blackRank
|
|
: 'BR';
|
|
|
|
whiteRank
|
|
: 'WR';
|
|
|
|
komi : 'KM';
|
|
|
|
result : 'RE'
|
|
| 'REsult'
|
|
;
|
|
|
|
rules : 'RU';
|
|
|
|
place : 'PC' | 'PlaCe';
|
|
|
|
application
|
|
: 'AP';
|
|
|
|
time : 'TM';
|
|
|
|
date : 'DT' | 'DaTe';
|
|
|
|
addBlack returns [SGFIdentifier sgfIdent]
|
|
: 'AB'{$sgfIdent = SGFIdentifier.ADD_BLACK;}
|
|
;
|
|
|
|
addWhite returns [SGFIdentifier sgfIdent]
|
|
: 'AW'{$sgfIdent = SGFIdentifier.ADD_WHITE;}
|
|
;
|
|
|
|
copyright
|
|
: 'CP';
|
|
|
|
username: 'US';
|
|
|
|
comment : 'C';
|
|
|
|
strValue
|
|
: (STRVALUE)+;
|
|
|
|
SPACE : ' ';
|
|
|
|
fragment DIGIT : '0'..'9';
|
|
|
|
COLON : ':';
|
|
|
|
MINUS : '-';
|
|
|
|
fragment PERIOD : '.';
|
|
|
|
COMMA : ',';
|
|
|
|
PLUS : '+';
|
|
|
|
SLASH : '/';
|
|
|
|
|
|
STRVALUE : (UCLETTER | LCLETTER | MINUS | DIGIT | SPACE | PERIOD | COMMA | PLUS | SLASH | COLON )+;
|
|
|
|
LPAREN : '(' ;
|
|
|
|
SEMICOLON : ';' ;
|
|
|
|
fragment UCLETTER : 'A'..'Z';
|
|
|
|
fragment LCLETTER : 'a'..'z';
|
|
|
|
LBRACKET
|
|
: '[';
|
|
|
|
RBRACKET
|
|
: ']';
|
|
|
|
RPAREN : ')';
|
|
|
|
//CR : '\r'{$channel=HIDDEN;};
|
|
|
|
//NEWLINE : '\n'{$channel=HIDDEN;};
|