| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2021-06-03 20:12:17 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2021-06-03 20:12:17 +0200 |
| commit | e9e5ba2b2612574fe3ff31305d20b673b095a06f (patch) | |
| tree | b167d1b4127709bd043a2afcc1427e35f54f4940 | |
| parent | de7d31799b420caf16b23fc9dd87efb088c09049 (diff) | |
...
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 | 235 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 273 | ||||
| -rw-r--r-- | src/core/src/tonkadur/fate/v1/parser/Parser.java | 84 |
3 files changed, 250 insertions, 342 deletions
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 92ca943..e21134a 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -7,18 +7,13 @@ lexer grammar FateLexer; fragment SEP: [ \t\r\n]+; fragment US: '_'?; - -fragment DICT_NS: 'dict:'; -fragment LIST_NS: 'list:'; -fragment SET_NS: 'set:'; -fragment STRUCT_NS: 'struct:'; - +fragment IMP: '!'; WS: SEP; L_PAREN: '('; R_PAREN: ')'; - +IMP_MARKER: IMP; FATE_VERSION_KW: L_PAREN 'fate'US'version' SEP+; @@ -63,201 +58,19 @@ DECLARE_LOCAL_VARIABLE_KW: L_PAREN 'local' SEP+; -ABS_KW: L_PAREN 'abs'('olute'?) SEP+; -CLAMP_KW: L_PAREN ('clamp') SEP+; -DIVIDE_KW: L_PAREN (('div''ide'?)|'/') SEP+; -MAX_KW: L_PAREN ('max'('imum'?)) SEP+; -MINUS_KW: L_PAREN ('minus'|'-') SEP+; -MIN_KW: L_PAREN ('min'('imum'?)) SEP+; -MODULO_KW: L_PAREN (('mod''ulo'?)|'%') SEP+; -PLUS_KW: L_PAREN ('plus'|'+') SEP+; -POWER_KW: L_PAREN (('pow''er'?)|'^'|'**'|) SEP+; -RANDOM_KW: L_PAREN (('rand''om'?)|'rnd') SEP+; -TIMES_KW: L_PAREN ('times'|'*') SEP+; - - - DICT_KW: L_PAREN 'dict'('ionary'?) SEP+; -DICT_FILTER_KW: L_PAREN DICT_NS 'filter' SEP+; -DICT_FOLD_KW: L_PAREN DICT_NS 'fold' SEP+; -DICT_FROM_LIST_KW: - L_PAREN ((DICT_NS'from'US'list')|(LIST_NS'to'US'dict'('ionary'?))) SEP+; -DICT_GET_KW: L_PAREN DICT_NS 'get' SEP+; -DICT_HAS_KW: L_PAREN DICT_NS 'has' SEP+; -DICT_KEYS_KW: L_PAREN DICT_NS ('get'US)?'keys' SEP+; -DICT_MAP_KW: L_PAREN DICT_NS 'map' SEP+; -DICT_MERGE_KW: L_PAREN DICT_NS 'merge' SEP+; -DICT_REMOVE_KW: L_PAREN DICT_NS ('rm'|'remove'|'del'|'delete') SEP+; -DICT_SET_KW: L_PAREN DICT_NS 'set' SEP+; -DICT_SIZE_KW: L_PAREN DICT_NS 'size' SEP+; -DICT_TO_LIST_KW: - L_PAREN ((DICT_NS'to'US'list')|(LIST_NS'from'US'dict'('ionary'?))) SEP+; -DICT_VALUES_KW: L_PAREN DICT_NS ('get'US)?'values' SEP+; -IMP_DICT_FILTER_KW: L_PAREN DICT_NS 'filter''!' SEP+; -IMP_DICT_FOLD_KW: L_PAREN DICT_NS 'fold''!' SEP+; -IMP_DICT_FROM_LIST_KW: - L_PAREN ((DICT_NS'from'US'list')|(LIST_NS'to'US'dict'('ionary'?)))'!' SEP+; -IMP_DICT_GET_KW: L_PAREN DICT_NS 'get''!' SEP+; -IMP_DICT_HAS_KW: L_PAREN DICT_NS 'has''!' SEP+; -IMP_DICT_KEYS_KW: L_PAREN DICT_NS ('get'US)?'keys''!' SEP+; -IMP_DICT_MAP_KW: L_PAREN DICT_NS 'map''!' SEP+; -IMP_DICT_MERGE_KW: L_PAREN DICT_NS 'merge''!' SEP+; -IMP_DICT_REMOVE_KW: L_PAREN DICT_NS ('rm'|'remove'|'del'|'delete')'!' SEP+; -IMP_DICT_SET_KW: L_PAREN DICT_NS 'set''!' SEP+; -IMP_DICT_TO_LIST_KW: - L_PAREN ((DICT_NS'to'US'list')|(LIST_NS'from'US'dict'('ionary'?)))'!' SEP+; -IMP_DICT_VALUES_KW: L_PAREN DICT_NS ('get'US)?'values''!' SEP+; - - - - LIST_KW: L_PAREN 'list' SEP+; -LIST_ADD_ALL_KW: L_PAREN LIST_NS 'add'US'all'(US'elements')? SEP+; -LIST_ADD_ALL_KW: L_PAREN LIST_NS 'add'US'all'(US'elements')? SEP+; -LIST_ADD_AT_KW: L_PAREN LIST_NS 'add'(US'element')?US'at' SEP+; -LIST_ADD_KW: L_PAREN LIST_NS 'add'(US'element')? SEP+; -LIST_COUNT_KW: L_PAREN LIST_NS 'count' SEP+; -LIST_FILTER_KW: L_PAREN LIST_NS 'filter' SEP+; -LIST_FOLDL_KW: L_PAREN LIST_NS 'foldl' SEP+; -LIST_FOLDR_KW: L_PAREN LIST_NS 'foldr' SEP+; -LIST_GET_KW: L_PAREN LIST_NS 'get' SEP+; -LIST_INDEXED_FILTER_KW: L_PAREN LIST_NS 'indexed'US'filter' SEP+; -LIST_INDEXED_MAP_KW: L_PAREN LIST_NS 'indexed'US'map' SEP+; -LIST_INDEXED_MERGE_KW: L_PAREN LIST_NS 'indexed'US'merge' SEP+; -LIST_INDEXED_PARTITION_KW: L_PAREN LIST_NS 'indexed'US'partition' SEP+; -LIST_INDEX_OF_KW: L_PAREN LIST_NS 'index'US'of' SEP+; -LIST_IS_EMPTY_KW: L_PAREN LIST_NS 'is'US'empty' SEP+; -LIST_IS_MEMBER_KW: L_PAREN LIST_NS (('is'US'member')|'contains'|'has') SEP+; -LIST_MAP_KW: L_PAREN LIST_NS 'map' SEP+; -LIST_MERGE_KW: L_PAREN LIST_NS 'merge' SEP+; -LIST_PARTITION_KW: L_PAREN LIST_NS 'partition' SEP+; -LIST_POP_LEFT_KW: L_PAREN LIST_NS 'pop'US'left' SEP+; -LIST_POP_RIGHT_KW: L_PAREN LIST_NS 'pop'US'right' SEP+; -LIST_PUSH_LEFT_KW: L_PAREN LIST_NS 'push'US'left' SEP+; -LIST_PUSH_RIGHT_KW: L_PAREN LIST_NS 'push'US'right' SEP+; -LIST_RANGE_KW: L_PAREN LIST_NS 'range' SEP+; -LIST_REMOVE_ALL_KW: L_PAREN LIST_NS 'remove'US'all' SEP+; -LIST_REMOVE_AT_KW: L_PAREN LIST_NS 'remove'US('element'?US)?'at' SEP+; -LIST_REMOVE_ONE_KW: L_PAREN LIST_NS 'remove'US'one' SEP+; -LIST_REVERSE_KW: L_PAREN LIST_NS 'reverse'(US'list')? SEP+; -LIST_SAFE_INDEXED_MERGE_KW: - L_PAREN LIST_NS (('safe'US'indexed')|('indexed'US'safe'))US'merge' SEP+; -LIST_SAFE_MERGE_KW: L_PAREN LIST_NS 'safe'US'merge' SEP+; -LIST_SET_KW: L_PAREN LIST_NS 'set' SEP+; -LIST_SHUFFLE_KW: L_PAREN LIST_NS 'shuffle' SEP+; -LIST_SIZE_KW: L_PAREN LIST_NS 'size' SEP+; -LIST_SORT_KW: L_PAREN LIST_NS 'sort' SEP+; -LIST_SUB_LIST_KW: L_PAREN LIST_NS 'sub'US'list' SEP+; -IMP_LIST_ADD_ALL_KW: L_PAREN LIST_NS 'add'US'all'(US'elements')?'!' SEP+; -IMP_LIST_ADD_AT_KW: L_PAREN LIST_NS 'add'(US'element')?US'at!' SEP+; -IMP_LIST_ADD_KW: L_PAREN LIST_NS 'add'(US'element')?'!' SEP+; -IMP_LIST_CLEAR_KW: L_PAREN LIST_NS 'clear!' SEP+; -IMP_LIST_FILTER_KW: L_PAREN LIST_NS 'filter!' SEP+; -IMP_LIST_INDEXED_FILTER_KW: L_PAREN LIST_NS 'indexed'US'filter!' SEP+; -IMP_LIST_INDEXED_MAP_KW: L_PAREN LIST_NS 'indexed'US'map!' SEP+; -IMP_LIST_INDEXED_MERGE_KW: L_PAREN LIST_NS 'indexed'US'merge!' SEP+; -IMP_LIST_INDEXED_PARTITION_KW: L_PAREN LIST_NS 'indexed'US'partition!' SEP+; -IMP_LIST_MAP_KW: L_PAREN LIST_NS 'map!' SEP+; -IMP_LIST_MERGE_KW: L_PAREN LIST_NS 'merge!' SEP+; -IMP_LIST_PARTITION_KW: L_PAREN LIST_NS 'partition!' SEP+; -IMP_LIST_POP_LEFT_KW: L_PAREN LIST_NS 'pop'US'left!' SEP+; -IMP_LIST_POP_RIGHT_KW: L_PAREN LIST_NS 'pop'US'right!' SEP+; -IMP_LIST_PUSH_LEFT_KW: L_PAREN LIST_NS 'push'US'left!' SEP+; -IMP_LIST_PUSH_RIGHT_KW: L_PAREN LIST_NS 'push'US'right!' SEP+; -IMP_LIST_REMOVE_ALL_KW: L_PAREN LIST_NS 'remove'US'all!' SEP+; -IMP_LIST_REMOVE_AT_KW: L_PAREN LIST_NS ('remove'US('elem''ent'?US)?'at!') SEP+; -IMP_LIST_REMOVE_ONE_KW: L_PAREN LIST_NS 'remove'US'one!' SEP+; -IMP_LIST_REVERSE_KW: L_PAREN LIST_NS 'reverse'(US'list')?'!' SEP+; -IMP_LIST_SAFE_INDEXED_MERGE_KW: - L_PAREN LIST_NS (('indexed'US'safe')|('safe'US'indexed'))US'merge!' SEP+; -IMP_LIST_SAFE_MERGE_KW: L_PAREN LIST_NS 'safe'US'merge!' SEP+; -IMP_LIST_SET_KW: L_PAREN LIST_NS 'set!' SEP+; -IMP_LIST_SHUFFLE_KW: L_PAREN LIST_NS 'shuffle!' SEP+; -IMP_LIST_SORT_KW: L_PAREN LIST_NS 'sort!' SEP+; -IMP_LIST_SUB_LIST_KW: L_PAREN LIST_NS 'sub'US'list!' SEP+; - - - - SET_KW: L_PAREN 'set' SEP+; -SET_ADD_ALL_KW: L_PAREN SET_NS 'add'US'all'(US'elements')? SEP+; -SET_ADD_KW: L_PAREN SET_NS 'add'(US'element')? SEP+; -SET_COUNT_KW: L_PAREN SET_NS 'count' SEP+; -SET_FILTER_KW: L_PAREN SET_NS 'filter' SEP+; -SET_FOLDL_KW: L_PAREN SET_NS foldl' SEP+; -SET_FOLDR_KW: L_PAREN SET_NS 'foldr' SEP+; -SET_GET_KW: L_PAREN SET_NS 'get' SEP+; -SET_INDEXED_FILTER_KW: L_PAREN SET_NS 'indexed'US'filter' SEP+; -SET_INDEXED_MAP_KW: L_PAREN SET_NS 'indexed'US'map' SEP+; -SET_INDEXED_MERGE_KW: L_PAREN SET_NS 'indexed'US'merge' SEP+; -SET_INDEXED_PARTITION_KW: L_PAREN SET_NS 'indexed'US'partition' SEP+; -SET_INDEX_OF_KW: L_PAREN SET_NS 'index'US'of' SEP+; -SET_IS_EMPTY_KW: L_PAREN SET_NS 'is'US'empty' SEP+; -SET_IS_MEMBER_KW: L_PAREN SET_NS ('is'US'member'|'contains'|'has') SEP+; -SET_MAP_KW: L_PAREN SET_NS 'map' SEP+; -SET_MERGE_KW: L_PAREN SET_NS 'merge' SEP+; -SET_PARTITION_KW: L_PAREN SET_NS 'partition' SEP+; -SET_POP_LEFT_KW: L_PAREN SET_NS 'pop'US'left' SEP+; -SET_POP_RIGHT_KW: L_PAREN SET_NS 'pop'US'right' SEP+; -SET_RANGE_KW: L_PAREN SET_NS 'range' SEP+; -SET_REMOVE_AT_KW: L_PAREN SET_NS ('remove'US('elem'('ent')?US)?'at') SEP+; -SET_REMOVE_ONE_KW: L_PAREN SET_NS 'remove'US'one' SEP+; -SET_SAFE_INDEXED_MERGE_KW: - L_PAREN SET_NS (('safe'US'indexed')|('indexed'US'safe'))US'merge' SEP+; -SET_SAFE_MERGE_KW: L_PAREN SET_NS 'safe'US'merge' SEP+; -SET_SET_KW: L_PAREN SET_NS 'set' SEP+; -SET_SIZE_KW: L_PAREN SET_NS 'size' SEP+; -IMP_SET_ADD_ALL_KW: L_PAREN SET_NS 'add'US'all'(US'elements')?'!' SEP+; -IMP_SET_ADD_KW: L_PAREN SET_NS 'add'(US'element')?'!' SEP+; -IMP_SET_CLEAR_KW: L_PAREN SET_NS 'clear!' SEP+; -IMP_SET_FILTER_KW: L_PAREN SET_NS 'filter!' SEP+; -IMP_SET_INDEXED_FILTER_KW: L_PAREN SET_NS 'indexed'US'filter!' SEP+; -IMP_SET_INDEXED_MAP_KW: L_PAREN SET_NS 'indexed'US'map!' SEP+; -IMP_SET_INDEXED_MERGE_KW: L_PAREN SET_NS 'indexed'US'merge!' SEP+; -IMP_SET_INDEXED_PARTITION_KW: L_PAREN SET_NS 'indexed'US'partition!' SEP+; -IMP_SET_MAP_KW: L_PAREN SET_NS 'map!' SEP+; -IMP_SET_MERGE_KW: L_PAREN SET_NS 'merge!' SEP+; -IMP_SET_PARTITION_KW: L_PAREN SET_NS 'partition!' SEP+; -IMP_SET_POP_LEFT_KW: L_PAREN SET_NS 'pop'US'left!' SEP+; -IMP_SET_POP_RIGHT_KW: L_PAREN SET_NS 'pop'US'right!' SEP+; -IMP_SET_REMOVE_AT_KW: L_PAREN SET_NS ('remove'US('elem'('ent')?US)?'at!') SEP+; -IMP_SET_REMOVE_ONE_KW: L_PAREN SET_NS 'remove'US'one!' SEP+; -IMP_SET_SAFE_INDEXED_MERGE_KW: - L_PAREN SET_NS (('indexed'US'safe')|('safe'US'indexed'))US'merge!' SEP+; -IMP_SET_SAFE_MERGE_KW: L_PAREN SET_NS 'safe'US'merge!' SEP+; - - - - -AND_KW: L_PAREN ('and'|'/\\') SEP+; -FALSE_KW: L_PAREN 'false' SEP* R_PAREN; -IMPLIES_KW: L_PAREN ('implies'|'=>'|'->') SEP+; -NOT_KW: L_PAREN ('not'|'~'|'!') SEP+; -ONE_IN_KW: L_PAREN ('exactly'US)?'one'(US'in')? SEP+; -OR_KW: L_PAREN ('or'|'\\/') SEP+; -TRUE_KW: L_PAREN 'true' SEP* R_PAREN; - - ENABLE_TEXT_EFFECT_KW: L_PAREN 'text'US'effect' SEP+; + NEWLINE_KW: L_PAREN 'newline' SEP* R_PAREN; -TEXT_JOIN_KW: L_PAREN TEXT_NS 'join' SEP+; TEXT_KW: L_PAREN 'text' SEP+; - - - - - CONS_KW: L_PAREN 'cons' SEP+; -CAR_KW: L_PAREN 'car' SEP+; -CDR_KW: L_PAREN 'cdr' SEP+; - - - COND_KW: L_PAREN 'cond' SEP+; DO_WHILE_KW: L_PAREN 'do'US'while' SEP+; @@ -269,34 +82,19 @@ IMP_BREAK_KW: L_PAREN 'break'('!'?) SEP* R_PAREN; IMP_CONTINUE_KW: L_PAREN 'continue'('!'?) SEP* R_PAREN; - - IF_ELSE_KW: L_PAREN 'if'US'else' SEP+; IF_KW: L_PAREN 'if' SEP+; - STRING_KW: L_PAREN 'string' SEP+; - - DEFAULT_KW: L_PAREN 'default' SEP+; CAST_KW: L_PAREN 'cast' SEP+; - -EQUALS_KW: L_PAREN ('equals'|'='|'=='|'eq') SEP+; -GREATER_EQUAL_THAN_KW: L_PAREN (('greater'US'equal'US'than')|'>='|'ge') SEP+; -GREATER_THAN_KW: L_PAREN (('greater'US'than')|'>'|'gt') SEP+; -LOWER_EQUAL_THAN_KW: L_PAREN (('lower'US'equal'US'than')|'=<'|'<='|'le') SEP+; -LOWER_THAN_KW: L_PAREN (('lower'US'than')|'<'|'lt') SEP+; - - - - IMP_ASSERT_KW: L_PAREN 'assert!' SEP+; IGNORE_ERROR_KW: L_PAREN 'ignore'US('error'|'warning') SEP+; @@ -309,11 +107,9 @@ EXTRA_COMPUTATION_KW: L_PAREN '$'; - -FIELD_KW: L_PAREN STRUCT_NS ('get'US)?'field' SEP+; -SET_FIELDS_KW: L_PAREN STRUCT_NS 'set'US'fields' SEP+; -IMP_SET_FIELDS_KW: L_PAREN STRUCT_NS 'set'US'fields!' SEP+; - +FIELD_ACCESS_KW: L_PAREN 'struct:get'(US'field')? SEP+; +SET_FIELDS_KW: L_PAREN 'struct:set'(US'fields')? SEP+; +IMP_SET_FIELDS_KW: L_PAREN 'struct:set'((US'fields!')|'!') SEP+; @@ -328,7 +124,6 @@ PROMPT_INTEGER_KW: L_PAREN 'prompt'US'int''eger'?'!' SEP+; LET_KW: L_PAREN 'let' SEP+; -AT_KW: L_PAREN 'at' SEP+; REF_KW: L_PAREN ( @@ -336,27 +131,11 @@ REF_KW: |('addr''ess'?(US'of')?) ) SEP+; -IMP_SET_KW: L_PAREN 'set'(US(('val''ue'?)|('var''iable'?)))?'!' SEP+; -VARIABLE_KW: L_PAREN 'var''iable'? SEP+; - - - - -ALLOCATE_KW: L_PAREN (('alloc''ate'?)|'malloc'|'new')'!' SEP+; -FREE_KW: L_PAREN ('free!'|'release!'|'destroy!') SEP+; - +VARIABLE_KW: L_PAREN 'var''iable'? SEP+; LAMBDA_KW: L_PAREN 'lambda' SEP+; -EVAL_KW: L_PAREN 'eval''uate'? SEP+; - - - - - - - SEQUENCE_KW: L_PAREN 'seq''uence'? SEP+; DONE_KW: L_PAREN 'done''!'? SEP* R_PAREN; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index ff7ea40..686fde2 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -1,8 +1,8 @@ -parser grammar TinyFateParser; +parser grammar FateParser; options { - tokenVocab = TinyFateLexer; + tokenVocab = FateLexer; } @header @@ -172,7 +172,7 @@ first_level_instruction ( start_origin, ($identifier.result), - ($type_list.result) + ($maybe_type_list.result) ); PARSER.get_world().extra_instructions().add(extra_instruction); @@ -200,7 +200,7 @@ first_level_instruction start_origin, ($type.result), ($identifier.result), - ($type_list.result) + ($maybe_type_list.result) ); PARSER.get_world().extra_computations().add(extra_computation); @@ -244,7 +244,7 @@ first_level_instruction new Event ( start_origin, - ($type_list.result), + ($maybe_type_list.result), ($identifier.result) ); @@ -267,7 +267,7 @@ first_level_instruction new TextEffect ( start_origin, - ($type_list.result), + ($maybe_type_list.result), ($identifier.result) ); @@ -283,7 +283,7 @@ first_level_instruction PARSER.get_origin_at ( ($DECLARE_GLOBAL_VARIABLE_KW.getLine()), - ($DECLARE_GLOBAl_VARIABLE_KW.getCharPositionInLine()) + ($DECLARE_GLOBAL_VARIABLE_KW.getCharPositionInLine()) ); new_variable = @@ -697,7 +697,7 @@ returns [Instruction result] { PARSER.increment_breakable_levels(); } - instr_cond_list WS* + instruction_cond_list WS* { PARSER.increase_local_variables_hierarchy(); } @@ -716,7 +716,7 @@ returns [Instruction result] ($SWITCH_KW.getCharPositionInLine()) ), ($computation.result), - ($instr_cond_list.result), + ($instruction_cond_list.result), ($instruction.result) ); } @@ -854,11 +854,8 @@ returns [Instruction result] /******************************************************************************/ | PLAYER_CHOICE_KW - { - // FIXME: handle player_choice limited local variables. - PARSER.push_choice_limited_variables_level(); - } - player_choice_list WS* + player_choice_list[Parser.generate_player_choice_data()] + WS* R_PAREN { $result = @@ -871,8 +868,6 @@ returns [Instruction result] ), ($player_choice_list.result) ); - - PARSER.pop_choice_limited_variables_level(); } | PROMPT_STRING_KW @@ -1029,7 +1024,7 @@ returns [List<Cons<Computation, Instruction>> result] $result.add ( - new Cons(($value.result), ($instruction.result)) + new Cons(($computation.result), ($instruction.result)) ); } WS* @@ -1038,14 +1033,15 @@ returns [List<Cons<Computation, Instruction>> result] } ; -player_choice_list returns [List<Instruction> result] +player_choice_list [Parser.PlayerChoiceData pcd] +returns [List<Instruction> result] @init { $result = new ArrayList<Instruction>(); } : ( - WS* player_choice + WS* player_choice[pcd] { $result.add($player_choice.result); } @@ -1056,7 +1052,7 @@ catch [final Throwable e] PARSER.handle_error(e); } -maybe_player_choice_list +maybe_player_choice_list [Parser.PlayerChoiceData pcd] returns [List<Instruction> result] @init { @@ -1064,7 +1060,7 @@ returns [List<Instruction> result] } : (WS* - player_choice + player_choice[pcd] { $result.add(($player_choice.result)); } @@ -1073,16 +1069,23 @@ returns [List<Instruction> result] } ; -player_choice +player_choice [Parser.PlayerChoiceData pcd] returns [Instruction result] /* * Do not use a separate Local Variable stack for the player choice - * instructions. + * instructions but do have one for any variable defined in 'for' or 'foreach' + * choices. */ : TEXT_OPTION_KW - L_PAREN WS* paragraph WS* R_PAREN WS* + L_PAREN WS* { + PARSER.enable_restricted_stack_of(pcd); + } + paragraph + WS* R_PAREN WS* + { + PARSER.disable_restricted_stack_of(pcd); PARSER.increase_local_variables_hierarchy(); } maybe_instruction_list WS* @@ -1104,8 +1107,12 @@ returns [Instruction result] } | EVENT_OPTION_KW - L_PAREN WS* WORD maybe_value_list WS* R_PAREN WS* { + PARSER.enable_restricted_stack_of(pcd); + } + L_PAREN WS* WORD maybe_computation_list WS* R_PAREN WS* + { + PARSER.disable_restricted_stack_of(pcd); PARSER.increase_local_variables_hierarchy(); } maybe_instruction_list WS* @@ -1130,12 +1137,12 @@ returns [Instruction result] ( origin, event, - ($maybe_value_list.result), + ($maybe_computation_list.result), ($maybe_instruction_list.result) ); } - | L_PAREN maybe_player_choice_list WS* R_PAREN + | L_PAREN maybe_player_choice_list[pcd] WS* R_PAREN { $result = new InstructionList @@ -1149,7 +1156,16 @@ returns [Instruction result] ); } - | IF_KW computation WS* player_choice_list WS* R_PAREN + | IF_KW + { + PARSER.enable_restricted_stack_of(pcd); + } + computation WS* + { + PARSER.disable_restricted_stack_of(pcd); + } + player_choice_list[pcd] WS* + R_PAREN { $result = IfInstruction.build @@ -1165,9 +1181,15 @@ returns [Instruction result] } | IF_ELSE_KW + { + PARSER.enable_restricted_stack_of(pcd); + } computation WS* - if_true=player_choice WS* - if_false=player_choice WS* + { + PARSER.disable_restricted_stack_of(pcd); + } + if_true=player_choice[pcd] WS* + if_false=player_choice[pcd] WS* R_PAREN { $result = @@ -1178,13 +1200,13 @@ returns [Instruction result] ($IF_ELSE_KW.getLine()), ($IF_ELSE_KW.getCharPositionInLine()) ), - ($non_text_value.result), + ($computation.result), ($if_true.result), ($if_false.result) ); } - | COND_KW player_choice_cond_list WS* R_PAREN + | COND_KW player_choice_cond_list[pcd] WS* R_PAREN { $result = CondInstruction.build @@ -1199,9 +1221,15 @@ returns [Instruction result] } | SWITCH_KW + { + PARSER.enable_restricted_stack_of(pcd); + } computation WS* - player_choice_switch_list WS+ - player_choice WS* + { + PARSER.disable_restricted_stack_of(pcd); + } + player_choice_switch_list[pcd] WS+ + player_choice[pcd] WS* R_PAREN { $result = @@ -1212,7 +1240,7 @@ returns [Instruction result] ($SWITCH_KW.getLine()), ($SWITCH_KW.getCharPositionInLine()) ), - ($value.result), + ($computation.result), ($player_choice_switch_list.result), ($player_choice.result) ); @@ -1220,15 +1248,28 @@ returns [Instruction result] | FOR_KW l0=L_PAREN - choice_for_variable_list WS* + { + PARSER.enable_restricted_stack_of(pcd); + PARSER.increase_local_variables_hierarchy(); + pcd.increase_variable_names_hierarchy(); + } + choice_for_variable_list[pcd] WS* R_PAREN WS* computation WS* l1=L_PAREN - choice_for_update_variable_list WS* + choice_for_update_variable_list[pcd] WS* R_PAREN WS* - player_choice_list WS* + { + PARSER.disable_restricted_stack_of(pcd); + } + player_choice_list[pcd] WS* R_PAREN { + pcd.decrease_variable_names_hierarchy(); + PARSER.enable_restricted_stack_of(pcd); + PARSER.decrease_local_variables_hierarchy(); + PARSER.disable_restricted_stack_of(pcd); + $result = For.build ( @@ -1261,7 +1302,14 @@ returns [Instruction result] } | FOR_EACH_KW - computation WS+ identifier + { + PARSER.enable_restricted_stack_of(pcd); + PARSER.increase_local_variables_hierarchy(); + } + computation WS+ + { + } + identifier { final Map<String, Variable> variable_map; final Variable new_variable; @@ -1270,7 +1318,7 @@ returns [Instruction result] elem_type = Type.ANY; - collection_type = ($non_text_value.result).get_type(); + collection_type = ($computation.result).get_type(); if (collection_type instanceof CollectionType) { @@ -1308,22 +1356,16 @@ returns [Instruction result] false ); - PARSER.add_context_variable(new_variable); + PARSER.add_local_variable(new_variable); + PARSER.disable_restricted_stack_of(pcd); } WS+ - { - PARSER.get_hierarchical_variables().push(new ArrayList()); - } - player_choice_list - { - for (final String s: PARSER.get_hierarchical_variables().pop()) - { - PARSER.get_local_variables().peekFirst().remove(s); - } - } - WS* + player_choice_list[pcd] WS* R_PAREN { + PARSER.enable_restricted_stack_of(pcd); + PARSER.decrease_local_variables_hierarchy(); + PARSER.disable_restricted_stack_of(pcd); $result = new ForEach ( @@ -1332,12 +1374,10 @@ returns [Instruction result] ($FOR_EACH_KW.getLine()), ($FOR_EACH_KW.getCharPositionInLine()) ), - ($non_text_value.result), + ($computation.result), ($identifier.result), ($player_choice_list.result) ); - - variable_map.remove(($identifier.result)); } ; catch [final Throwable e] @@ -1345,7 +1385,7 @@ catch [final Throwable e] PARSER.handle_error(e); } -player_choice_cond_list +player_choice_cond_list [Parser.PlayerChoiceData pcd] returns [List<Cons<Computation, Instruction>> result] @init { @@ -1354,6 +1394,7 @@ returns [List<Cons<Computation, Instruction>> result] condition = null; $result = new ArrayList<Cons<Computation, Instruction>>(); + // TODO: pcd enable. } : ( @@ -1362,6 +1403,7 @@ returns [List<Cons<Computation, Instruction>> result] (L_PAREN WS* computation WS+) { condition = ($computation.result); + // TODO: pcd disable. } ) | @@ -1379,10 +1421,11 @@ returns [List<Cons<Computation, Instruction>> result] ), ($something_else.text).substring(1).trim() ); + // TODO: pcd disable. } ) ) - player_choice WS* R_PAREN + player_choice[pcd] WS* R_PAREN { $result.add(new Cons(condition, ($player_choice.result))); } @@ -1396,15 +1439,22 @@ catch [final Throwable e] PARSER.handle_error(e); } -player_choice_switch_list +player_choice_switch_list [Parser.PlayerChoiceData pcd] returns [List<Cons<Computation, Instruction>> result] @init { $result = new ArrayList<Cons<Computation, Instruction>>(); + // todo: pcd enable } : ( - L_PAREN WS* computation WS* player_choice WS* R_PAREN + L_PAREN + WS* computation + { + //todo: pcd disable + } + WS* player_choice[pcd] WS* + R_PAREN { $result.add(new Cons(($computation.result), ($player_choice.result))); } @@ -1499,10 +1549,10 @@ returns [Type result] ( PARSER.get_origin_at ( - ($WORD.getLine()), - ($WORD.getCharPositionInLine()) + ($L_PAREN.getLine()), + ($L_PAREN.getCharPositionInLine()) ), - ($WORD.text) + ($identifier.result) ); $result = t.build(type_list); @@ -1579,7 +1629,7 @@ returns [List<Cons<Variable, Computation>> result] } ) ) - WS+ value WS* R_PAREN + WS+ computation WS* R_PAREN { final Variable v; @@ -1591,26 +1641,14 @@ returns [List<Cons<Variable, Computation>> result] ($L_PAREN.getLine()), ($L_PAREN.getCharPositionInLine()) ), - ($value.result).get_type(), + ($computation.result).get_type(), var_name, false ); - if (PARSER.current_context_variable_level_has(var_name)) - { - ErrorManager.handle - ( - new DuplicateLocalVariableException - ( - variables.get(var_name), - v - ) - ); - } - PARSER.add_context_variable(v); - $result.add(new Cons(v, ($value.result))); + $result.add(new Cons(v, ($computation.result))); } )* { @@ -1621,15 +1659,13 @@ catch [final Throwable e] PARSER.handle_error(e); } -choice_for_update_variable_list +choice_for_update_variable_list [Parser.PlayerChoiceData pcd] returns [List<Instruction> result] @init { - Collection<String> allowed_variables; String var_name; Origin origin; - allowed_variables = PARSER.get_choice_limited_variables().peek(); var_name = null; origin = null; @@ -1682,7 +1718,7 @@ returns [List<Instruction> result] ) ); - if (!allowed_variables.contains(var_name)) + if (!pcd.can_update_variable(var_name)) { ErrorManager.handle ( @@ -1699,15 +1735,13 @@ catch [final Throwable e] PARSER.handle_error(e); } -choice_for_variable_list +choice_for_variable_list [Parser.PlayerChoiceData pcd] returns [List<Instruction> result] @init { - Collection<String> allowed_variables; String var_name; Origin origin; - allowed_variables = PARSER.get_choice_limited_variables().peek(); var_name = null; origin = null; @@ -1745,6 +1779,21 @@ returns [List<Instruction> result] ) WS+ computation WS* R_PAREN { + final Variable new_var; + + new_var = + new Variable + ( + origin, + ($computation.result).get_type(), + var_name, + false + ); + + $result.add(new LocalVariable(new_var)); + + PARSER.add_context_variable(v); + $result.add ( SetValue.build @@ -1755,7 +1804,7 @@ returns [List<Instruction> result] ) ); - allowed_variables.add(var_name); + pcd.mark_name_as_editable(var_name); } )* { @@ -2027,7 +2076,7 @@ returns [Computation result] } L_PAREN WS* variable_list WS* R_PAREN { - PARSER.add_local_variables(($variable_lists.result).as_map()); + PARSER.add_local_variables(($variable_list.result).as_map()); } WS* computation @@ -2080,19 +2129,6 @@ returns [Computation result] | CAST_KW type WS+ computation WS* R_PAREN { - final Origin target_type_origin; - final Type target_type; - - target_type_origin = - PARSER.get_origin_at - ( - ($WORD.getLine()), - ($WORD.getCharPositionInLine()) - ); - - target_type = - PARSER.get_world().types().get(target_type_origin, ($WORD.text)); - $result = Cast.build ( @@ -2101,13 +2137,13 @@ returns [Computation result] ($CAST_KW.getLine()), ($CAST_KW.getCharPositionInLine()) ), - target_type, + $type.result, ($computation.result), false ); } - | SET_FIELDS_KW computation WS* field_computation_list WS* R_PAREN + | SET_FIELDS_KW computation WS* field_value_list WS* R_PAREN { /* * A bit of a lazy solution: build field references, then extract the data @@ -2119,7 +2155,7 @@ returns [Computation result] for ( final Cons<Origin, Cons<String, Computation>> entry: - ($field_computation_list.result) + ($field_value_list.result) ) { final FieldReference fr; @@ -2185,7 +2221,7 @@ returns [Computation result] | ENABLE_TEXT_EFFECT_KW L_PAREN WORD WS+ - value_list WS* + computation_list WS* R_PAREN WS+ paragraph WS* R_PAREN @@ -2212,7 +2248,7 @@ returns [Computation result] ($ENABLE_TEXT_EFFECT_KW.getCharPositionInLine()) ), effect, - ($value_list.result), + ($computation_list.result), ($paragraph.result) ); } @@ -2305,6 +2341,10 @@ returns [List<Cons<Computation, Computation>> result] { } ; +catch [final Throwable e] +{ + PARSER.handle_error(e); +} maybe_computation_list returns [List<Computation> result] @@ -2313,12 +2353,31 @@ returns [List<Computation> result] $result = new ArrayList<Computation>(); } : - ( + (WS+ computation { ($result).add(($computation.result)); } )* + { + } +; +catch [final Throwable e] +{ + PARSER.handle_error(e); +} + +computation_list +returns [List<Computation> result] +@init +{ + $result = new ArrayList<Computation>(); +} +: + computation + { + ($result).add(($computation.result)); + } (WS+ computation { @@ -2328,3 +2387,7 @@ returns [List<Computation> result] { } ; +catch [final Throwable e] +{ + PARSER.handle_error(e); +} diff --git a/src/core/src/tonkadur/fate/v1/parser/Parser.java b/src/core/src/tonkadur/fate/v1/parser/Parser.java index d746fb5..3caa7b2 100644 --- a/src/core/src/tonkadur/fate/v1/parser/Parser.java +++ b/src/core/src/tonkadur/fate/v1/parser/Parser.java @@ -20,13 +20,13 @@ import tonkadur.fate.v1.lang.World; public class Parser { - final World world; - final Context context; + protected final World world; + protected final Context context; - LocalVariables local_variables; + protected LocalVariables local_variables; - int breakable_levels; - int continue_levels; + protected int breakable_levels; + protected int continue_levels; public Parser (final World world) { @@ -196,12 +196,12 @@ public class Parser throws IOException { final CommonTokenStream tokens; - final TinyFateLexer lexer; - final TinyFateParser parser; + final FateLexer lexer; + final FateParser parser; - lexer = new TinyFateLexer(CharStreams.fromFileName(filename)); + lexer = new FateLexer(CharStreams.fromFileName(filename)); tokens = new CommonTokenStream(lexer); - parser = new TinyFateParser(tokens); + parser = new FateParser(tokens); if (origin != null) { @@ -223,7 +223,73 @@ public class Parser } } + public PlayerChoiceData generate_player_choice_data () + { + return new Parser.PlayerChoiceData(this); + } + + public void enable_restricted_variable_stack_of (final PlayerChoiceData pcd) + { + pcd.previous_variable_stack = get_local_variables_stack(); + + restore_local_variables_stack(pcd.restricted_including_variables_stack); + } + + public void disable_restricted_stack_of (final PlayerChoiceData pcd) + { + restore_local_variables_stack(pcd.previous_variable_stack); + } + + public static class LocalVariables extends Deque<Map<String, Variable>> { } + + public static class PlayerChoiceData + { + protected final Parser parent; + protected final LocalVariables restricted_including_variables_stack; + protected LocalVariables previous_variable_stack; + protected final Deque<Set<String>> player_choice_variable_names; + + protected PlayerChoiceData (final Parser parent) + { + this.parent = parent; + + previous_variable_stack = parent.get_local_variables_stack(); + + // Note: clone makes a shallow copy. + restricted_including_variables_stack = previous_variable_stack.clone(); + + player_choice_variable_names = new ArrayDeque<Set<String>>(); + } + + public void increase_variable_names_hierarchy () + { + player_choice_variable_names.push(new HashSet<String>()); + } + + public void decrease_variable_names_hierarchy () + { + player_choice_variable_names.pop(); + } + + public void mark_name_as_editable (final String name) + { + player_choice_variable_names.peek().add(name); + } + + public boolean can_update_variable (final String name) + { + for (final Set<String> variable_names: player_choice_variable_names) + { + if (variables_names.has(name)) + { + return true; + } + } + + return false; + } + } } |


