git @ Cat's Eye Technologies Fountain / 10154e9
`--fuel-factor` requires that `--convert-loops` has also been given. Chris Pressey 4 months ago
3 changed file(s) with 21 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
3232 of storage, this limits Fountain to simulating a Linear Bounded Automaton
3333 (LBA), which is the known bounds for parsing Context-Sensitive Languages
3434 (CSLs).
35
36 `--fuel-factor` may only be specified when `--convert-loops` is also
37 specified.
3538
3639 Also moved project history to its own `HISTORY.md` file.
3740
6060 args <- getArgs
6161 let (flags, args') = parseFlags defaultFlags args
6262 let output = if (suppressNewline flags) then putStr else putStrLn
63 fuel <- case (convertLoops flags, fuelFactor flags) of
64 (False, Just _) -> do
65 putStrLn "Error: --fuel-factor cannot be specified without --convert-loops"
66 usage
67 (_, _) -> do
68 return Fuel.FuelState{
69 Fuel.currentFuel=(initialFuel flags),
70 Fuel.fuelFactor=(fuelFactor flags)
71 }
6372 case args' of
6473 ["version"] -> do
6574 putStrLn "fountain 0.7"
7786 let grammar' = Preprocessor.preprocessGrammarForParsing grammar (convertLoops flags)
7887 text <- loadText textFileName
7988 let start = getStartSymbol grammar' flags
80 let fuel = Fuel.FuelState{ Fuel.currentFuel=(initialFuel flags), Fuel.fuelFactor=(fuelFactor flags) }
8189 let initialState = Parser.constructState grammar' start text initialParams fuel
8290 let finalState = Parser.parseFrom grammar' start initialState
8391 output $ if (dumpState flags) then show finalState else formatParseResult $ Parser.obtainResult finalState
8694 grammar <- loadSource grammarFileName
8795 let grammar' = Preprocessor.preprocessGrammarForGeneration grammar (convertLoops flags)
8896 let start = getStartSymbol grammar' flags
89 let fuel = Fuel.FuelState{ Fuel.currentFuel=(initialFuel flags), Fuel.fuelFactor=(fuelFactor flags) }
9097 let initialState = Generator.constructState grammar' start (seed flags) initialParams fuel
9198 let finalState = Generator.generateFrom grammar' start initialState
9299 output $ if (dumpState flags) then show finalState else formatGenerateResult $ Generator.obtainResult finalState
2323
2424 # Fuel factor 0 won't ever be enough to sustain anything.
2525
26 echo -n "((*))" | $FOUNTAIN --dump-state --initial-fuel 0 --fuel-factor 0 parse eg/nested-parens.fountain -- n=2 | \
26 echo -n "((*))" | $FOUNTAIN --dump-state --convert-loops --initial-fuel 0 --fuel-factor 0 parse eg/nested-parens.fountain -- n=2 | \
2727 expect 'Left "Out of fuel"'
2828
2929 # But if you have enough fuel initially, it doesn't have to be sustainable.
3030
31 echo -n "((*))" | $FOUNTAIN --dump-state --initial-fuel 4 --fuel-factor 0 parse eg/nested-parens.fountain -- n=2 | \
31 echo -n "((*))" | $FOUNTAIN --dump-state --convert-loops --initial-fuel 4 --fuel-factor 0 parse eg/nested-parens.fountain -- n=2 | \
3232 expect 'Right (Parsing {input = "", store = fromList [(Var "a",2),(Var "n",2)], fuel = FuelState {currentFuel = 1, fuelFactor = Just 0}})'
3333
3434 # Fuel factor 1 is sufficient for this parsing problem.
3535
36 echo -n "((*))" | $FOUNTAIN --dump-state --initial-fuel 1 --fuel-factor 1 parse eg/nested-parens.fountain -- n=2 | \
36 echo -n "((*))" | $FOUNTAIN --dump-state --convert-loops --initial-fuel 1 --fuel-factor 1 parse eg/nested-parens.fountain -- n=2 | \
3737 expect 'Right (Parsing {input = "", store = fromList [(Var "a",2),(Var "n",2)], fuel = FuelState {currentFuel = 3, fuelFactor = Just 1}})'
3838
3939 # If you can do something with fuel factor 1, you can do it with fuel factor 2 as well.
4040
41 echo -n "((*))" | $FOUNTAIN --dump-state --initial-fuel 1 --fuel-factor 2 parse eg/nested-parens.fountain -- n=2 | \
41 echo -n "((*))" | $FOUNTAIN --dump-state --convert-loops --initial-fuel 1 --fuel-factor 2 parse eg/nested-parens.fountain -- n=2 | \
4242 expect 'Right (Parsing {input = "", store = fromList [(Var "a",2),(Var "n",2)], fuel = FuelState {currentFuel = 8, fuelFactor = Just 2}})'
4343
4444 ### Fuel Consumption During Generation ###
4545
4646 # Given enough fuel, it does generate.
4747
48 $FOUNTAIN --fuel-factor 1 --initial-fuel 4 generate eg/nested-parens.fountain n=3 | \
48 $FOUNTAIN --convert-loops --fuel-factor 1 --initial-fuel 4 generate eg/nested-parens.fountain n=3 | \
4949 expect '(((*)))'
5050
5151 # It does need some initial fuel.
5252
53 $FOUNTAIN --fuel-factor 1 --initial-fuel 0 generate eg/nested-parens.fountain n=3 | \
53 $FOUNTAIN --convert-loops --fuel-factor 1 --initial-fuel 0 generate eg/nested-parens.fountain n=3 | \
5454 expect 'Failure'
5555
5656 # Fuel gain, and usage, is proportional to the given n in this case.
5757
58 $FOUNTAIN --fuel-factor 1 --initial-fuel 4 generate eg/nested-parens.fountain n=10 | \
58 $FOUNTAIN --convert-loops --fuel-factor 1 --initial-fuel 4 generate eg/nested-parens.fountain n=10 | \
5959 expect '((((((((((*))))))))))'
6060
6161 # If fuel factor is 0 it is reliant on the initial fuel.
6262
63 $FOUNTAIN --fuel-factor 0 --initial-fuel 4 generate eg/nested-parens.fountain n=10 | \
63 $FOUNTAIN --convert-loops --fuel-factor 0 --initial-fuel 4 generate eg/nested-parens.fountain n=10 | \
6464 expect 'Failure'
6565
66 $FOUNTAIN --fuel-factor 0 --initial-fuel 15 generate eg/nested-parens.fountain n=10 | \
66 $FOUNTAIN --convert-loops --fuel-factor 0 --initial-fuel 15 generate eg/nested-parens.fountain n=10 | \
6767 expect '((((((((((*))))))))))'