From 0d74c4bcfaedfc5ba517406010bea1497473c7e7 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Mon, 25 Dec 2017 21:03:43 +0000 Subject: [PATCH] Tidied the parser a bit --- src/advent25/advent25.hs | 50 +++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/advent25/advent25.hs b/src/advent25/advent25.hs index 656c775..aa3ff4d 100644 --- a/src/advent25/advent25.hs +++ b/src/advent25/advent25.hs @@ -90,39 +90,41 @@ lexeme = L.lexeme sc integer = lexeme L.integer symbol = L.symbol sc fullstop = symbol "." +colon = symbol ":" +dash = symbol "-" -commandP = between (symbol "-") fullstop +machineDescriptionP = machineify <$> startStateP <*> stepsP <*> manyStateRulesP + where machineify initial limit rules = + ( emptyMachine { tState = initial, stepsRemaining = limit } + , rules + ) -writeValueP = (symbol "1" *> pure True) <|> (symbol "0" *> pure False) -writeP = commandP ((symbol "Write the value") *> writeValueP) +startStateP = (symbol "Begin in state") *> stateP <* fullstop +stepsP = (symbol "Perform a diagnostic checksum after") *> integer <* (symbol "steps") <* fullstop + +manyStateRulesP = M.unions <$> (stateRulesP `sepBy` space) -directionP = (symbol "left" *> pure -1) <|> (symbol "right" *> pure 1) -tapeMovementP = commandP ((symbol "Move one slot to the") *> directionP) +stateRulesP = rulify <$> stateDefP <*> (stateWhenP `sepBy` space) + where rulify s ts = M.fromList $ map (\(v, t) -> ((s, v), t)) ts -newStateP = commandP ((symbol "Continue with state") *> (some letterChar)) +stateWhenP = (,) <$> currentValueP <*> stateTransitionP + +stateDefP = (symbol "In state") *> stateP <* colon +currentValueP = (symbol "If the current value is") *> writeValueP <* colon stateTransitionP = stify <$> writeP <*> tapeMovementP <*> newStateP where stify w t s = StateTransition {writeValue = w, newState = s, tapeMovement = t} - -currentValueP = (symbol "If the current value is") *> writeValueP <* (symbol ":") - -stateWhenP = (,) <$> currentValueP <*> stateTransitionP - -stateDefP = (symbol "In state") *> (some letterChar) <* (symbol ":") - -stateRulesP = rulify <$> stateDefP <*> (stateWhenP `sepBy` space) - where rulify s ts = M.fromList $ map (\(v, t) -> ((s, v), t)) ts - -manyStateRulesP = M.unions <$> (stateRulesP `sepBy` space) -startStateP = (symbol "Begin in state") *> (some letterChar) <* fullstop -stepsP = (symbol "Perform a diagnostic checksum after") *> integer <* (symbol "steps") <* fullstop +commandP = between dash fullstop + +writeP = commandP ((symbol "Write the value") *> writeValueP) +tapeMovementP = commandP ((symbol "Move one slot to the") *> directionP) +newStateP = commandP ((symbol "Continue with state") *> stateP) + +stateP = some letterChar +directionP = (symbol "left" *> pure -1) <|> (symbol "right" *> pure 1) +writeValueP = (symbol "1" *> pure True) <|> (symbol "0" *> pure False) -machineDescriptionP = machineify <$> startStateP <*> stepsP <*> manyStateRulesP - where machineify initial limit rules = - ( emptyMachine { tState = initial, stepsRemaining = limit } - , rules - ) successfulParse :: Text -> (Machine, Rules) successfulParse input = -- 2.34.1