/* * This is a file describing a simplified version of the baseball * play-by-play notation used by the Retrosheet project * (http://www.retrosheet.org) * * The notation described here is a subset of that accepted by the * tools published on that website, but is intended to permit all * possible plays to be expressed accurately and completely. * Further, it is the goal of this grammar (or a refinement thereof) * to formally express various "validation" restrictions in the * notation (such as conditions under which a double play is possible, * or to guarantee that runners do not pass each other or wind up * at the same base). * * This file may be processed by the yacc/bison program to produce * a C program which reads play strings on standard input and outputs * an "ok"/"error" report if the string does/does not match the grammar. * * The grammar rules are organized top-down: the entry rules for the * grammar appear at the top, and referenced rules are (generally) found * further down in the file. * * Taken as written, the grammar is as "general" as possible, and does * not take into account preconditions, such as the number of outs * and the location of baserunners at the start of the play. These * are denoted in comments as preconditions. Postconditions are * also noted after some rules: these indicate restrictions on what * strings are legal in the grammar after a rule is used, even though * they would be accepted by the basic "general" yacc implementation * you generate from this file. (Make sense?) * * This version of the file is dated February 1, 2005, and was * prepared by T. Turocy */ %token ENDSTRING %% /* This is the "entry" rule, which essentially is a yacc technicality * to be able to read one line at a time */ playstring: play ENDSTRING { return 0; } /* This is the *real* "entry" rule of the grammar. * This file makes no assumptions about the type of event that is going * to be encountered. In practice, an application may be * capturing pitch-by-pitch data. In this case, possible event * types are restricted by the knowledge of the pitch on which the * event occurred: * * 'X': ball_in_play * intentional ball four: intentional_walk * uninentional ball four: walk * third strike ('C', 'S', 'T'): strikeout * other pitch not resulting in walk or strikeout: pitch_event * 'H': hit_by_pitch * 'F': foul_error * * Thus this rule is broken up into these classifications. In an * application with pitch information, the appropriate rule should * be used as the "entry" rule of the parser. */ play: ball_in_play | pitch_event | intentional_walk | walk | strikeout | hit_by_pitch | foul_error /* * An event where the batter hits the ball in play. */ ball_in_play: batted_out | reach_on_error | fielders_choice | hit_single | hit_double | hit_triple | hit_homerun | interference /* * An event that occurs when the batter has not hit the ball in play, * but does not terminate the batter's turn at bat. */ pitch_event: balk | wild_pitch | passed_ball | stolen_base | caught_stealing | pickoff | other_adv | indifference /************************************************************************* * Principal event: Single *************************************************************************/ /* Primary event type is a single. * Differences from broader Diamondware notation: * - The /BR flag denoting a single awarded by rule when a batted ball * hits a baserunner is not supported. * * Preconditions: * - For the first rule given, the bases must be empty. * * Postconditions: * - If no advancement for the batter is specified, advancement to * first base is assumed. An explicit B-1 for the batter is prohibited. * - Advancement for all baserunners must be specified, even if * baserunners do not advance. (For example, with a runner on second * a string like S.2-2 is legal and required if the baserunner does * not advance) */ hit_single: single_main | single_main '.' advancement single_main: single_generic | single_dp | single_tp /* * Generic single event. * General format: S [fielded-by] [trajectory] * Both the identity of the fielder and the batted ball type/location are * optional. * Valid examples (in roughly increasing order of detail) * S ("single") * S7 ("single, fielded by LF") * S7/G ("ground single fielded by LF") * S/G ("ground single") * S7/G56 ("ground single between short and third, fielded by LF") * S/G56 ("ground single hit between short and third") */ single_generic: 'S' fielded_by_opt traj_opt /* * Single, followed by a double play. Rare but possible (happens a few * times a year in MLB.) * * Differs from single_generic examples only by putting a /DP flag * between the fielder (if present) and trajectory (if present). * * Preconditions: * - Must be at least one runner on base, and less than two outs. * * Postconditions: * - There must be at least two putouts specified in the advancement * portion of the string. */ single_dp: 'S' fielded_by_opt dp_flag traj_opt /* * Single, followed by a triple play. Rare but possible (happens a few * times a year in MLB.) * * Differs from single_generic examples only by putting a /TP flag * between the fielder (if present) and trajectory (if present). * * Preconditions: * - Must be at least two runners on base, and no outs. * * Postconditions: * - There must be exactly three putouts specified in the advancement * portion of the string. */ single_tp: 'S' fielded_by_opt tp_flag traj_opt /************************************************************************* * Principal event: Double *************************************************************************/ /* Primary event type is a double. * Differences from broader Diamondware notation: None known. * * Preconditions: * - For the first rule given, the bases must be empty. * * Postconditions: * - If no advancement for the batter is specified, advancement to * second base is assumed. An explicit B-1, B-2, or BX1 for the batter is * prohibited. * - Advancement for all baserunners must be specified, even if * baserunners do not advance. (In practice, no advancement on a double * is only possible for a runner on third, and that's *quite* unlikely.) * * Note that we resist making a two-base advance on a 'DGR' mandatory, * since it is possible a ground rule might allow a runner on first to * score. (In fact, the author has some memory that such a play has * occurred, but does not have specifics.) */ hit_double: double_main | double_main '.' advancement double_main: double_generic | double_dp /* * Generic single event. * Essentially the same as for doubles, except the code * 'GR' is permitted in the fielded-by position: this denotes a * "ground-rule" double. (Note for the purist: the notation does * not distinguish between a true "ground rule" and the "automatic" double * arising when a ball bounces over a fence.) */ double_generic: 'D' double_fielded_by_opt traj_opt /* * Double, followed by a double play. Quite rare, unless you're the * Brooklyn Dodgers! * * Differs from double_generic examples only by putting a /DP flag * between the fielder (if present) and trajectory (if present). * * Preconditions: * - Must be at least one runner on base, and less than two outs. * * Postconditions: * - There must be at least two putouts specified in the advancement * portion of the string. */ double_dp: 'D' double_fielded_by_opt dp_flag traj_opt /* special case for doubles: 'ground rule' double */ double_fielded_by_opt: fielded_by_opt | 'G' 'R' /************************************************************************* * Principal event: Triple *************************************************************************/ /* Primary event type is a triple. * Differences from broader Diamondware notation: None known. * * Preconditions: * - For the first rule given, the bases must be empty. * * Postconditions: * - If no advancement for the batter is specified, advancement to * third base is assumed. An explicit B-1, B-2, B-3, BX1, or BX2 is * prohibited. * - Advancement for all baserunners must be specified, and * all baserunners must score. */ hit_triple: triple_main | triple_main '.' advancement triple_main: 'T' fielded_by_opt traj_opt /************************************************************************* * Principal event: Home run *************************************************************************/ /* Primary event is a home run. * Differences from broader Diamondware notation: * - Diamondware also excepts just 'H' for a home run. * * Preconditions: * - For the first rule given, the bases must be empty. * * Postconditions: * - No advancement for the batter may be specified, *unless* it is * of the form B-H(UR) or B-H(TUR) to indicate that the batter's run * is unearned. Conversely, the only way to indicate the batter's * run is unearned is to explicitly indicate the batter's advance * as above. * - All runners must score. * * Notes: * - If the home run event specifies a fielded-by fielder, it is * to be intepreted as an inside-the-park HR. If it does not specify * a fielder, it is to be interpreted as an outside-the-park HR. * - In the case of an outside-the-park HR, a location code, if specified, * indicates the outfield area where the ball left play. This limits * the possible location codes to '7LD', '7D', '78XD', '8XD', '89XD', * '9D', '9LD'. */ hit_homerun: homerun_main | homerun_main '.' advancement homerun_main: 'H' 'R' fielded_by_opt traj_opt /************************************************************************* * Principal event: Walk *************************************************************************/ /* Primary event is a walk. * * Postconditions: * - No advancement for the batter may be specified, unless the * batter advances past first, or is out attempting to advance */ walk: 'W' advancement_opt | 'W' '+' 'W' 'P' '.' advancement | 'W' '+' 'P' 'B' '.' advancement | walk_and_sb advancement_opt | walk_and_cs advancement_opt | walk_and_po advancement_opt | walk_and_oa advancement /* * A stolen base occurs on ball four. Note that a runner can't be * credited with a stolen base of second in this scenario. * * Preconditions: * - There must be a non-forced runner on second for SB3 to appear. * - There must be a non-forced runner on third for SBH to appear. */ walk_and_sb: 'W' '+' 'S' 'B' '3' | 'W' '+' 'S' 'B' 'H' | 'W' '+' 'S' 'B' 'H' ';' 'S' 'B' '3' /* * A caught stealing occurs on ball four. Note that a runner can't be * caught stealing second base in this scenario. * * Preconditions: * - For the double play flag to appear, there must be less than two outs. * - There must be a non-forced runner on second for CS3 to appear. * - There must be a non-forced runner on third for CSH to appear. * * Postconditions: * - If the double play flag appears, at least two outs must be indicated * in the play string. */ walk_and_cs: 'W' '+' 'C' 'S' '3' cs_fielder_play dp_flag_opt | 'W' '+' 'C' 'S' 'H' cs_fielder_play dp_flag_opt | 'W' '+' 'C' 'S' 'H' cs_fielder_play ';' 'C' 'S' '3' cs_fielder_play dp_flag /* * A pickoff occurs on ball four. * * Preconditions: * - For the double play flag to appear, there must be less than two outs. * - There must be a non-forced runner on second for PO2 to appear * - There must be a non-forced runner on third for PO3 to appear. * * Postconditions: * - If the double play flag appears, at least two outs must be indicated * in the play string. */ walk_and_po: 'W' '+' 'P' 'O' '2' cs_fielder_play dp_flag_opt | 'W' '+' 'P' 'O' '3' cs_fielder_play dp_flag_opt /* * An out advancing occurs on ball four. */ walk_and_oa: 'W' '+' 'O' 'A' /************************************************************************* * Principal event: Intentional walk *************************************************************************/ /* Primary event is an intentional walk. * * Note that the only difference between a walk event and an intentional * walk event is that the intentional walk starts with 'IW' instead of * 'W'. Therefore, we just reference the rules for walks after indicating * the initial 'I'. */ intentional_walk: 'I' walk /************************************************************************* * Principal event: Strikeout *************************************************************************/ strikeout: kcode advancement_opt | kcode '+' 'W' 'P' '.' advancement | kcode '+' 'P' 'B' '.' advancement | kcode '+' sb_seq advancement_opt | kcode '+' 'C' 'S' cs_base '(' fielder_list ')' dp_flag advancement_opt | kcode '+' 'C' 'S' cs_base '(' fielder_list ')' tp_flag advancement_opt | kcode '+' 'C' 'S' cs_base '(' fielder_list 'E' fielder ')' dp_flag_opt advancement_opt | kcode '+' 'P' 'O' po_base '(' fielder_list ')' dp_flag advancement_opt | kcode '+' 'P' 'O' po_base '(' 'E' fielder ')' dp_flag_opt advancement_opt | kcode '+' 'P' 'O' po_base '(' fielder_list 'E' fielder ')' advancement_opt | kcode '+' 'D' 'I' '.' advancement | kcode '+' 'O' 'A' dp_flag_opt '.' advancement | 'K' dp_flag '.' advancement | 'K' tp_flag '.' advancement kcode: 'K' | 'K' fielder_list | 'K' fielder_list 'E' fielder /************************************************************************* * Principal event: Hit by pitch *************************************************************************/ /* Note: Diamondware also accepts 'HBP' */ hit_by_pitch: 'H' 'P' | 'H' 'P' '.' hbp_advance hbp_advance: hbp_r3_advance ';' hbp_r2_advance ';' hbp_r1_advance | hbp_r2_advance ';' hbp_r1_advance | hbp_r1_advance hbp_r3_advance: '3' '-' 'H' hbp_r2_advance: '2' '-' '3' hbp_r1_advance: '1' '-' '2' /************************************************************************* * Principal event: Catcher interference *************************************************************************/ /* Note: Diamondware also accepts 'C/En' where 'n' is a fielder number. Usually, this is '2', but there are instances where this code is used for interference on other fielders. */ interference: 'C' '.' int_advance int_advance: int_r3_advance ';' int_r2_advance ';' int_r1_advance ';' int_b_advance | int_r2_advance ';' int_r1_advance ';' int_b_advance | int_r1_advance ';' int_b_advance | int_b_advance /* Obscure fact: RBI *is* awarded on catcher's interference! */ int_r3_advance: '3' '-' 'H' int_r2_advance: '2' '-' '3' int_r1_advance: '1' '-' '2' int_b_advance: 'B' '-' '1' /************************************************************************* * Principal event: Balk *************************************************************************/ balk: 'B' 'K' '.' balk_advance balk_advance: balk_r3_advance | balk_r3_advance ';' balk_r2_advance | balk_r3_advance ';' balk_r1_advance | balk_r3_advance ';' balk_r2_advance ';' balk_r1_advance | balk_r2_advance | balk_r2_advance ';' balk_r1_advance | balk_r1_advance balk_r3_advance: '3' '-' 'H' norbi_flag balk_r2_advance: '2' '-' '3' balk_r1_advance: '1' '-' '2' /************************************************************************* * Principal event: Wild pitch *************************************************************************/ wild_pitch: 'W' 'P' '.' advancement /************************************************************************* * Principal event: Passed ball *************************************************************************/ passed_ball: 'P' 'B' '.' advancement /************************************************************************* * Principal event: Stolen base *************************************************************************/ stolen_base: sb_seq | sb_seq '.' advancement /* * A sb_seq is a "phrase" which indicates credit for a single, double, * or triple steal. This can appear at the beginning of a stolen base * event on its own, or as part of a walk or strikeout event. * * Precondition: * - A runner must be on the preceding base in order for a SB to be * credited. */ sb_seq: 'S' 'B' '2' | 'S' 'B' '3' | 'S' 'B' 'H' | 'S' 'B' '3' ';' 'S' 'B' '2' | 'S' 'B' 'H' ';' 'S' 'B' '2' | 'S' 'B' 'H' ';' 'S' 'B' '3' | 'S' 'B' 'H' ';' 'S' 'B' '3' ';' 'S' 'B' '2' /************************************************************************* * Principal event: Caught stealing *************************************************************************/ /* Missing from this: possible double plays, including two CS on same play */ caught_stealing: cs_seq | cs_seq '.' advancement cs_base: 'H' | '3' | '2' cs_seq: 'C' 'S' '2' cs_fielder_play | 'C' 'S' '3' cs_fielder_play | 'C' 'S' 'H' cs_fielder_play | 'C' 'S' '3' cs_fielder_play ';' 'C' 'S' '2' cs_fielder_play dp_flag | 'C' 'S' 'H' cs_fielder_play ';' 'C' 'S' '2' cs_fielder_play dp_flag | 'C' 'S' 'H' cs_fielder_play ';' 'C' 'S' '3' cs_fielder_play dp_flag | 'C' 'S' 'H' cs_fielder_play ';' 'C' 'S' '3' cs_fielder_play ';' 'C' 'S' '2' cs_fielder_play tp_flag cs_fielder_play: '(' fielder_list ')' | '(' fielder_list 'E' fielder ')' | '(' 'E' fielder ')' /************************************************************************* * Principal event: Pickoff *************************************************************************/ pickoff: 'P' 'O' po_base '(' fielder_list ')' | 'P' 'O' po_base '(' fielder_list ')' '.' advancement | 'P' 'O' po_base '(' 'E' fielder ')' | 'P' 'O' po_base '(' 'E' fielder ')' '.' advancement | 'P' 'O' po_base '(' 'E' fielder '/' 'T' 'H' ')' | 'P' 'O' po_base '(' 'E' fielder '/' 'T' 'H' ')' '.' advancement | 'P' 'O' po_base '(' fielder_list 'E' fielder ')' | 'P' 'O' po_base '(' fielder_list 'E' fielder ')' '.' advancement | 'P' 'O' caught_stealing po_base: '1' | '2' | '3' /************************************************************************* * Principal event: Defensive indifference *************************************************************************/ indifference: 'D' 'I' '.' indiff_advance indiff_advance: indiff_r3_advance | indiff_r3_advance ';' indiff_r2_advance | indiff_r3_advance ';' indiff_r1_advance | indiff_r3_advance ';' indiff_r2_advance ';' indiff_r1_advance | indiff_r2_advance | indiff_r2_advance ';' indiff_r1_advance | indiff_r1_advance indiff_r3_advance: '3' '-' 'H' '(' 'N' 'R' ')' indiff_r2_advance: '2' '-' '3' indiff_r1_advance: '1' '-' '2' /************************************************************************* * Principal event: Other advancement *************************************************************************/ /* Mostly these occur when a runner attempts to advance on a would-be wild pitch or passed ball, but is thrown out. */ other_adv: 'O' 'A' '.' advancement /************************************************************************* * Principal event: Foul error *************************************************************************/ /* Note that we could restrict the trajectory zones here */ foul_error: 'F' 'L' 'E' fielder batted_out_traj /************************************************************************* * Principal event: Reach on error *************************************************************************/ reach_on_error: 'E' fielder batted_out_traj advancement_opt | 'E' fielder '/' 'T' 'H' batted_out_traj advancement_opt | 'E' fielder '/' 'S' 'H' batted_out_traj advancement_opt | 'E' fielder '/' 'T' 'H' '/' 'S' 'H' batted_out_traj advancement_opt | 'E' fielder '/' 'S' 'F' batted_out_traj advancement_opt /************************************************************************* * Principal event: Fielder's choice *************************************************************************/ /* The notation uses fielder's choice for two cases: the case where a non-forced runner is put out allowing the batter to reach, and the case where any play on an advancing runner fails due to an error. Note that the forceout case is handled by the 'generic' batted out event, even though in the Official Rules, a forceout is in fact a fielder's choice. */ fielders_choice: 'F' 'C' fielder batted_out_traj advancement_opt | 'F' 'C' fielder '/' 'S' 'H' batted_out_traj advancement_opt | 'F' 'C' fielder '/' 'D' 'P' batted_out_traj advancement_opt /************************************************************************* * Principal event: Generic batted ball out *************************************************************************/ /* A batted out is where the primary play is a groundout, flyout, etc. May also consist of primary outs where batter is safe on a muff. Note that no force plays are possible. */ batted_out: simple_out | sacrifice | continuation_dp | continuation_tp | safe_on_muff | simple_force | force_and_dp | gdp_batter_lastout | gdp_batter_reverseforce | gdp_batter_safe | triple_play | fielder_list '(' 'B' ')' fielder_list '(' '3' ')' fielder_list '(' '2' ')' tp_flag batted_out_traj advancement_opt /* * The simple_out is the most generic (and most common) of plays: * the batter is put out, no other runners are put out. */ simple_out: fielder_list batted_out_traj | fielder_list batted_out_traj '.' advancement sacrifice: fielder_list sac_flag batted_out_traj advancement_opt | fielder_list sac_flag dp_flag batted_out_traj advancement_opt /* * A continuation_dp is a double play that occurs when the batter is * put out "normally" (i.e., a batted ball caught in the air or a * bounded ball thrown to first), and a second runner is put out * subsequently (by trying to advance, or by failing to retouch his * original base on a caught ball). */ continuation_dp: fielder_list dp_flag batted_out_traj advancement_opt continuation_tp: fielder_list tp_flag batted_out_traj advancement_opt /* * A simple_force is a batted ball out where one baserunner is forced out. * The number in parentheses corresponds to the *originating* base of * a baserunner * * Preconditions: * - The base indicated must be a base where there's a baserunner forced * to run. * * Postconditions: * - The baserunner indicated in the force play cannot appear in the * advancement stanza. * * Notes: * - While a force out on a fly ball or pop fly doesn't happen in baseball, * it is generally considered permissible to write 46(1)/FO/P if, * for example, a pop fly drops behind the second baseman, who throws * to second to force a runner on first who had to hold up due to the * popup. Hence, there is no trajectory restriction on this play. */ simple_force: fielder_list '(' '1' ')' '/' 'F' 'O' batted_out_traj advancement_opt | fielder_list '(' '2' ')' '/' 'F' 'O' batted_out_traj advancement_opt | fielder_list '(' '3' ')' '/' 'F' 'O' batted_out_traj advancement_opt /* * A force_and_dp is a batted ball out where one baserunner is forced out. * Subsequently, another runner is put out, but not in a force or * reverse-force situation. * The number in parentheses corresponds to the *originating* base of * the baserunner who is forced out * * Preconditions: * - The base indicated must be a base where there's a baserunner forced * to run. * * Postconditions: * - The baserunner indicated in the force play cannot appear in the * advancement stanza. * - There must be another putout indicated in the advancement section * on the batter or another baserunner (other than the one forced). */ force_and_dp: fielder_list '(' '3' ')' '/' 'F' 'O' dp_flag batted_out_traj advancement_opt | fielder_list '(' '2' ')' '/' 'F' 'O' dp_flag batted_out_traj advancement_opt | fielder_list '(' '1' ')' '/' 'F' 'O' dp_flag batted_out_traj advancement_opt /* * The (base) notation is used *only* for force plays in this restricted * version. In Diamondware, it is sometimes also used to indicate when * a runner is caught off base on a fly ball. Instead, use notation such * as 1X1 to indicate this. */ gdp_batter_lastout: fielder_list '(' '3' ')' fielder_list '/' 'G' 'D' 'P' batted_out_traj advancement_opt | fielder_list '(' '2' ')' fielder_list '/' 'G' 'D' 'P' batted_out_traj advancement_opt | fielder_list '(' '1' ')' fielder_list '/' 'G' 'D' 'P' batted_out_traj advancement_opt gdp_batter_reverseforce: fielder_list '(' 'B' ')' fielder_list '(' '1' ')' gdp_flag batted_out_traj advancement_opt | fielder_list '(' 'B' ')' fielder_list '(' '2' ')' gdp_flag batted_out_traj advancement_opt | fielder_list '(' 'B' ')' fielder_list '(' '3' ')' gdp_flag batted_out_traj advancement_opt gdp_batter_safe: fielder_list '(' '3' ')' fielder_list '(' '2' ')' gdp_flag batted_out_traj advancement_opt | fielder_list '(' '3' ')' fielder_list '(' '1' ')' gdp_flag batted_out_traj advancement_opt | fielder_list '(' '2' ')' fielder_list '(' '1' ')' gdp_flag batted_out_traj advancement_opt | fielder_list '(' '2' ')' fielder_list '(' '3' ')' gdp_flag batted_out_traj advancement_opt | fielder_list '(' '1' ')' fielder_list '(' '2' ')' gdp_flag batted_out_traj advancement_opt | fielder_list '(' '1' ')' fielder_list '(' '3' ')' gdp_flag batted_out_traj advancement_opt /* * These are triple plays that occur on ground balls due to force plays. * Many varieties are *possible*, but by far the most likely one is * the around-the-horn triple play (which made Gary Gaetti famous) * For example: fielders(2)fielders(1)fielders/TP */ triple_play: fielder_list '(' '3' ')' fielder_list '(' '1' ')' fielder_list '(' '1' ')' tp_flag batted_out_traj advancement_opt | fielder_list '(' '3' ')' fielder_list '(' '2' ')' fielder_list tp_flag batted_out_traj advancement_opt | fielder_list '(' '3' ')' fielder_list '(' '1' ')' fielder_list '(' '2' ')' tp_flag batted_out_traj advancement_opt | fielder_list '(' '3' ')' fielder_list '(' '1' ')' fielder_list tp_flag batted_out_traj advancement_opt | fielder_list '(' '2' ')' fielder_list '(' '3' ')' fielder_list '(' '1' ')' tp_flag batted_out_traj advancement_opt | fielder_list '(' '2' ')' fielder_list '(' '3' ')' fielder_list tp_flag batted_out_traj advancement_opt | fielder_list '(' '2' ')' fielder_list '(' '1' ')' fielder_list '(' '3' ')' tp_flag batted_out_traj advancement_opt | fielder_list '(' '2' ')' fielder_list '(' '1' ')' fielder_list tp_flag batted_out_traj advancement_opt | fielder_list '(' '1' ')' fielder_list '(' '3' ')' fielder_list '(' '2' ')' tp_flag batted_out_traj advancement_opt | fielder_list '(' '1' ')' fielder_list '(' '3' ')' fielder_list tp_flag batted_out_traj advancement_opt | fielder_list '(' '1' ')' fielder_list '(' '2' ')' fielder_list '(' '3' ')' tp_flag batted_out_traj advancement_opt | fielder_list '(' '1' ')' fielder_list '(' '2' ')' fielder_list tp_flag batted_out_traj advancement_opt safe_on_muff: fielder_list 'E' fielder batted_out_traj '.' reach_on_muff_adv | fielder_list 'E' fielder '/' 'S' 'H' batted_out_traj '.' reach_on_muff_adv batted_out_traj: trajectory | trajectory '/' 'F' 'L' | traj_and_loc /* These are the plays where the batter reaches on a muffed throw */ /* note that if the batter scores, he *must* be unearned for the pitcher */ reach_on_muff_adv: muff_batter_adv | muff_r1_adv ';' muff_batter_adv | muff_r2_adv ';' muff_batter_adv | muff_r2_adv ';' muff_r1_adv ';' muff_batter_adv | muff_r3_adv ';' muff_batter_adv | muff_r3_adv ';' muff_r1_adv ';' muff_batter_adv | muff_r3_adv ';' muff_r2_adv ';' muff_batter_adv | muff_r3_adv ';' muff_r2_adv ';' muff_r1_adv ';' muff_batter_adv muff_r3_adv: '3' '-' 'H' | '3' '-' 'H' '(' 'N' 'R' ')' muff_r2_adv: '2' '-' '3' advance_nonout_play_opt | '2' '-' 'H' | '2' '-' 'H' advance_nonout_play | '2' '-' 'H' '(' 'N' 'R' ')' | '2' '-' 'H' advance_nonout_play '(' 'N' 'R' ')' muff_r1_adv: '1' '-' '2' | '1' '-' '3' advance_nonout_play_opt | '1' '-' 'H' advance_nonout_play_opt | '1' 'X' '2' advance_outonbases | '1' 'X' '3' advance_outonbases | '1' 'X' 'H' advance_outonbases muff_batter_adv: 'B' '-' '1' | 'B' '-' '2' advance_nonout_play_opt | 'B' '-' '3' advance_nonout_play_opt | 'B' '-' 'H' advance_nonout_play '(' 'U' 'R' ')' | 'B' '-' 'H' '(' 'U' 'R' ')' | 'B' 'X' '1' advance_outonbases | 'B' 'X' '2' advance_outonbases | 'B' 'X' '3' advance_outonbases | 'B' 'X' 'H' advance_outonbases /************************************************************************* * Batted balls: Trajectory and location flags *************************************************************************/ trajectory: '/' bunt_flag_opt 'G' | '/' bunt_flag_opt 'F' | '/' bunt_flag_opt 'L' | '/' bunt_flag_opt 'P' bunt_flag_opt: | 'B' traj_and_loc: trajectory location traj: trajectory | trajectory location traj_opt: | traj location: '1' | '1' '3' | '1' '5' | '1' 'S' | '2' | '2' 'F' | '2' '3' | '2' '3' 'F' | '2' '5' | '2' '5' 'F' | '3' 'S' 'F' | '3' 'F' | '3' 'D' 'F' | '3' 'S' | '3' | '3' 'D' | '3' '4' 'S' | '3' '4' | '3' '4' 'D' | '4' 'S' | '4' | '4' 'D' | '4' 'M' 'S' | '4' 'M' | '4' 'M' 'D' | '6' 'M' 'S' | '6' 'M' | '6' 'M' 'D' | '6' 'S' | '6' | '6' 'D' | '5' '6' 'S' | '5' '6' | '5' '6' 'D' | '5' 'S' | '5' | '5' 'D' | '5' 'S' 'F' | '5' 'F' | '5' 'D' 'F' | '7' 'L' 'S' 'F' | '7' 'L' 'S' | '7' 'S' | '7' '8' 'S' | '8' 'S' | '8' '9' 'S' | '9' 'S' | '9' 'L' 'S' | '9' 'L' 'S' 'F' | '7' 'L' 'F' | '7' 'L' | '7' | '7' '8' | '8' | '8' '9' | '9' | '9' 'L' | '9' 'L' 'F' | '7' 'L' 'D' 'F' | '7' 'L' 'D' | '7' 'D' | '7' '8' 'D' | '8' 'D' | '8' '9' 'D' | '9' 'D' | '9' 'L' 'D' | '9' 'L' 'D' 'F' | '7' '8' 'X' 'D' | '8' 'X' 'D' | '8' '9' 'X' 'D' /************************************************************************* * Fielding credits *************************************************************************/ /* a fielder_list is a sequence of fielder touches, with no errors */ fielder_list: fielder | fielder fielder_list /* we include the extension of using '0' to denote the tenth fielder in softball */ fielder: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' /* Fielder who fielded a base hit. This is an optional value. */ fielded_by_opt: | fielder /************************************************************************* * Generic advancement format *************************************************************************/ /* These are "generic" rules that express runner advancement. They don't take into account information like the event type, etc., nor do they impose any consistency on the advancements. These should be replaced by "customized" ones in the final products. */ advancement_opt: | '.' advancement advancement: advancement_r3_adv | advancement_r3_adv ';' advancement_r2_adv | advancement_r3_adv ';' advancement_r2_adv ';' advancement_b_adv | advancement_r3_adv ';' advancement_r1_adv | advancement_r3_adv ';' advancement_r1_adv ';' advancement_b_adv | advancement_r3_adv ';' advancement_b_adv | advancement_r3_adv ';' advancement_r2_adv ';' advancement_r1_adv | advancement_r3_adv ';' advancement_r2_adv ';' advancement_r1_adv ';' advancement_b_adv | advancement_r2_adv | advancement_r2_adv ';' advancement_b_adv | advancement_r2_adv ';' advancement_r1_adv | advancement_r2_adv ';' advancement_r1_adv ';' advancement_b_adv | advancement_r1_adv | advancement_r1_adv ';' advancement_b_adv | advancement_b_adv advancement_r3_adv: '3' '-' '3' | '3' '-' 'H' | '3' '-' 'H' advance_scoring_play | '3' 'X' '3' advance_outonbases | '3' 'X' 'H' advance_outonbases advancement_r2_adv: '2' '-' '2' | '2' '-' '3' | '2' '-' '3' advance_nonout_play | '2' '-' 'H' | '2' '-' 'H' advance_scoring_play | '2' 'X' '2' advance_outonbases | '2' 'X' '3' advance_outonbases | '2' 'X' 'H' advance_outonbases advancement_r1_adv: '1' '-' '1' | '1' '-' '2' | '1' '-' '2' advance_nonout_play | '1' '-' '3' | '1' '-' '3' advance_nonout_play | '1' '-' 'H' | '1' '-' 'H' advance_scoring_play | '1' 'X' '1' advance_outonbases | '1' 'X' '2' advance_outonbases | '1' 'X' '3' advance_outonbases | '1' 'X' 'H' advance_outonbases advancement_b_adv: 'B' '-' '1' advance_nonout_play_opt | 'B' '-' '2' advance_nonout_play_opt | 'B' '-' '3' advance_nonout_play_opt | 'B' '-' 'H' advance_scoring_play | 'B' 'X' '1' advance_outonbases | 'B' 'X' '2' advance_outonbases | 'B' 'X' '3' advance_outonbases | 'B' 'X' 'H' advance_outonbases /************************************************************************* * Runner advancement modifiers *************************************************************************/ advance_nonout_play_opt: | advance_nonout_play /* These are plays that advance a runner without causing a putout. With the bases empty, these basically involve muffs and throwing errors. (Advancement on throws is possible for other situations.) */ advance_nonout_play: '(' 'E' fielder ')' advance_nonout_play_opt | '(' 'E' fielder '/' 'T' 'H' ')' advance_nonout_play_opt | '(' 'T' 'H' ')' advance_nonout_play_opt | '(' 'W' 'P' ')' advance_nonout_play_opt /* the WP modifier is technically *only* valid on a SB play */ | '(' 'P' 'B' ')' advance_nonout_play_opt /* the PB modifier is technically *only* valid on a SB play */ advance_scoring_play_opt: | advance_scoring_play advance_scoring_play: '(' 'E' fielder ')' advance_scoring_play_opt | '(' 'E' fielder '/' 'T' 'H' ')' advance_scoring_play_opt | '(' 'T' 'H' ')' advance_scoring_play_opt | '(' 'W' 'P' ')' advance_scoring_play_opt /* the WP modifier is technically *only* valid on a SB play */ | '(' 'P' 'B' ')' advance_scoring_play_opt /* the PB modifier is technically *only* valid on a SB play */ | '(' 'N' 'R' ')' /* no-RBI flag ends list of advancement flags */ /* A muff advance occurs when a batter is safe because a fielder muffs a throw, or drops the ball on a tag. In the Retrosheet notation, these are still scored using the 'X' advancement notation, since the runner would have been out except for the muff. */ advance_muff_play: '(' fielder_list 'E' fielder ')' advance_outonbases | '(' fielder_list 'E' fielder ')' advance_error_play: '(' 'E' fielder ')' advance_outonbases | '(' 'E' fielder '/' 'T' 'H' ')' advance_outonbases | '(' 'T' 'H' ')' advance_outonbases advance_outonbases: advance_muff_play | advance_error_play | advance_out advance_out: '(' fielder_list ')' /************************************************************************* * General flags and modifiers *************************************************************************/ /* * These are flags and modifiers that may appear in multiple rules * We gather them here to help make the semantics and organization * of the rules clearer, and so we don't have to repeat these strings * of characters everywhere. */ /* * General note on double and triple plays: * The Diamondware notation permits several types of flag for double plays * including /FDP, /LDP, /BPDP. This restricted notation admits only * two: /DP and /GDP. The latter is reserved for plays that fall into * the statistical category "grounded into double play". * * Similarly, Diamondware software permits things like /GTP for grounded * into triple play. However, there are no official statistical categories * for such an event; therefore, all triple plays are written with the * /TP flag. As an interesting statistical note, a triple play is * *never* considered a GDP officially! Therefore, something like * /GDP/TP doesn't make sense, and isn't permitted in this specification. */ dp_flag: '/' 'D' 'P' dp_flag_opt: | dp_flag gdp_flag: '/' 'G' 'D' 'P' tp_flag: '/' 'T' 'P' /* * A flag indicating a sacrifice was credited to the batter. * * Preconditions: * - There must be at least one baserunner, and less than two out. * */ sac_flag: '/' 'S' 'H' | '/' 'S' 'F' norbi_flag: '(' 'N' 'R' ')' %% #include char playstring[256]; int yylex(void) { extern int yylval; yylval = getc(stdin); if (yylval != '\n') { strncat(playstring, (char *) &yylval, 1); } else { yylval = ENDSTRING; } return yylval; } int yyerror(char *s) { // fprintf(stderr, "%s\n", s); return 0; } int main(int argc, char *argv[]) { int foo; while (!feof(stdin)) { strcpy(playstring, ""); if (yyparse()) { do { foo = getchar(); if (foo != '\n') { strncat(playstring, (char *) &foo, 1); } } while (!feof(stdin) && foo != '\n'); fprintf(stdout, "%s: error\n", playstring); } else { fprintf(stdout, "%s: ok\n", playstring); } } }