parsley 2.0.0.0 → 2.0.0.1
raw patch · 60 files changed
+235/−5994 lines, 60 filesdep −arraydep −attoparsecdep −bytestringdep ~basedep ~template-haskelldep ~textPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: array, attoparsec, bytestring, criterion, megaparsec, mtl, parsec, parsley-garnish
Dependency ranges changed: base, template-haskell, text
API changes (from Hackage documentation)
- Parsley.ParserOps: instance (x GHC.Types.~ Parsley.Internal.Core.Defunc.Defunc) => Parsley.ParserOps.ParserOps x
- Parsley.ParserOps: instance Parsley.ParserOps.ParserOps Parsley.Internal.Common.Utils.WQ
- Parsley.Precedence: instance (x GHC.Types.~ Parsley.Internal.Core.Defunc.Defunc) => Parsley.Precedence.GOps x
- Parsley.Precedence: instance Parsley.Precedence.GOps Parsley.Internal.Common.Utils.WQ
+ Parsley.ParserOps: instance (x GHC.Types.~ Parsley.Internal.Common.Utils.WQ) => Parsley.ParserOps.ParserOps x
+ Parsley.ParserOps: instance Parsley.ParserOps.ParserOps Parsley.Internal.Core.Defunc.Defunc
+ Parsley.Precedence: instance (x GHC.Types.~ Parsley.Internal.Common.Utils.WQ) => Parsley.Precedence.GOps x
+ Parsley.Precedence: instance Parsley.Precedence.GOps Parsley.Internal.Core.Defunc.Defunc
- Parsley: class Quapplicative (q :: Type -> Type)
+ Parsley: class Quapplicative (q :: TYPE LiftedRep -> Type)
- Parsley: type Code (a :: TYPE r) = Q TExp a
+ Parsley: type Code (a :: TYPE r) = Code Q a
Files
- ChangeLog.md +45/−40
- benchmarks/BrainfuckBench/Attoparsec/Parser.hs +0/−17
- benchmarks/BrainfuckBench/Handrolled/Parser.hs +0/−26
- benchmarks/BrainfuckBench/Happy/Parser.y +0/−33
- benchmarks/BrainfuckBench/Main.hs +0/−66
- benchmarks/BrainfuckBench/Megaparsec/Parser.hs +0/−19
- benchmarks/BrainfuckBench/Parsec/Parser.hs +0/−18
- benchmarks/BrainfuckBench/Parsley/Parser.hs +0/−67
- benchmarks/BrainfuckBench/Shared.hs +0/−35
- benchmarks/JavascriptBench/Attoparsec/Parser.hs +0/−242
- benchmarks/JavascriptBench/Happy/Parser.y +0/−466
- benchmarks/JavascriptBench/Main.hs +0/−63
- benchmarks/JavascriptBench/Megaparsec/Parser.hs +0/−244
- benchmarks/JavascriptBench/Parsec/Parser.hs +0/−244
- benchmarks/JavascriptBench/Parsley/Parser.hs +0/−263
- benchmarks/JavascriptBench/Shared.hs +0/−95
- benchmarks/NandlangBench/Bison/Nandlang.tab.c +0/−1601
- benchmarks/NandlangBench/Bison/Parser.hs +0/−15
- benchmarks/NandlangBench/Bison/lex.yy.c +0/−1948
- benchmarks/NandlangBench/Main.hs +0/−28
- benchmarks/NandlangBench/Parsley/Functions.hs +0/−19
- benchmarks/NandlangBench/Parsley/Parser.hs +0/−104
- benchmarks/Shared/Attoparsec/Extended.hs +0/−77
- benchmarks/Shared/BenchmarkUtils.hs +0/−40
- benchmarks/Shared/Megaparsec/Extended.hs +0/−73
- benchmarks/Shared/Parsec/Extended.hs +0/−70
- parsley.cabal +35/−28
- src/ghc/Parsley.hs +2/−3
- src/ghc/Parsley/Alternative.hs +0/−0
- src/ghc/Parsley/Applicative.hs +6/−2
- src/ghc/Parsley/Char.hs +0/−0
- src/ghc/Parsley/Combinator.hs +0/−0
- src/ghc/Parsley/Debug.hs +0/−0
- src/ghc/Parsley/Defunctionalized.hs +0/−0
- src/ghc/Parsley/Fold.hs +4/−9
- src/ghc/Parsley/InputExtras.hs +1/−0
- src/ghc/Parsley/ParserOps.hs +2/−2
- src/ghc/Parsley/Precedence.hs +2/−2
- src/ghc/Parsley/Register.hs +0/−0
- src/ghc/Parsley/Selective.hs +7/−1
- test/Parsley/Alternative/Parsers.hs +0/−0
- test/Parsley/Alternative/Test.hs +0/−0
- test/Parsley/Applicative/Parsers.hs +0/−0
- test/Parsley/Applicative/Test.hs +0/−0
- test/Parsley/Char/Parsers.hs +0/−0
- test/Parsley/Char/Test.hs +0/−0
- test/Parsley/Combinator/Parsers.hs +19/−0
- test/Parsley/Combinator/Test.hs +15/−1
- test/Parsley/Fold/Parsers.hs +11/−7
- test/Parsley/Fold/Test.hs +1/−1
- test/Parsley/Precedence/Parsers.hs +15/−10
- test/Parsley/Precedence/Test.hs +0/−0
- test/Parsley/Register/Parsers.hs +9/−9
- test/Parsley/Register/Test.hs +0/−0
- test/Parsley/Selective/Parsers.hs +0/−0
- test/Parsley/Selective/Test.hs +0/−0
- test/Parsley/Tests.hs +2/−0
- test/Regression/Parsers.hs +17/−1
- test/Regression/Tests.hs +42/−5
- test/TestUtils.hs +0/−0
ChangeLog.md view
@@ -1,63 +1,68 @@ # Revision history for `parsley` -## 0.1.0.0 -- 2021-05-22+## 2.0.0.1 -- 2023-08-20 -* First version. Released on an unsuspecting world.+* Support for 9.6+* Removed use of `Text16` from the base API, it has been deprecated. -## 0.1.0.1 -- 2021-05-22+## 2.0.0.0 -- 2021-11-24 -* Moved tests and benchmarks into a subproject, which will be easier later down the line.-* Removed useless `dump-core` flag (only used by test and bench, not by the library).-* Fleshed out README properly!+* Incorporated API naming conventions from _Design Patterns for Parser Combinators_.+ * `chainPre` -> `prefix`+ * `chainPost` -> `postfix`+ * `chainl1'` -> `infixl1`+ * `chainr1'` -> `infixr1`+ * `pfoldr` -> `manyr`+ * `pfoldl` -> `manyl`+ * `pfoldr1` -> `somer`+ * `pfoldl1` -> `somel`+* Reworked the `precedence` combinator system in line with the paper: the horrible overloading+ has gone now!+* Added in the `ParserOps` and `Debug` modules.+* Added `RANGES` to the `Defunc` API.+* Renamed `runParser` to `parse`.+* Moved some functionality to `Parsley.Char`.+* Added `digit`, `letter`, and `letterOrDigit`. -## 0.1.1.0 -- 2021-06-10+## 1.0.2.0 -- 2021-11-14 -* Added `IF_S`, `LAM_S` and `LET_S` to `Defunc`, which can be used with overloaded syntax-* Admin: Removed `idioms-plugin` and `lift-plugin` from the test suite, depending on `parsley-garnish` instead-* Fixed building with GHC 9+* Added `local_` combinator to `Register`.+* Added `localModify` and `localModify_` combinators to `Register`. -## 1.0.0.0 -- 2021-06-12+## 1.0.1.0 -- 2021-11-13 -* Factored all of the `Parsley.Internal` modules out into `parsley-core` package+* Added `line` and `col` combinators.+* Added `pos` combinator. -## 1.0.0.1 -- 2021-06-29+## 1.0.0.3 -- 2021-10-29 -* Improved implementation of `oneOf` and `noneOf` to use ranges and not exhaustive character search+* Support for `parsley-core-2.0.0` and `parsley-core-1.7.1`.+* Re-exports less from `parsley-core`, instead using (currently hidden) redefinition. ## 1.0.0.2 -- 2021-08-13 * Added small optimisation to accomodate new core changes: added `try` for all top-level parsers. -## 1.0.0.3 -- 2021-10-29+## 1.0.0.1 -- 2021-06-29 -* Support for `parsley-core-2.0.0` and `parsley-core-1.7.1`.-* Re-exports less from `parsley-core`, instead using (currently hidden) redefinition.+* Improved implementation of `oneOf` and `noneOf` to use ranges and not exhaustive character search -## 1.0.1.0 -- 2021-11-13+## 1.0.0.0 -- 2021-06-12 -* Added `line` and `col` combinators.-* Added `pos` combinator.+* Factored all of the `Parsley.Internal` modules out into `parsley-core` package -## 1.0.2.0 -- 2021-11-14+## 0.1.1.0 -- 2021-06-10 -* Added `local_` combinator to `Register`.-* Added `localModify` and `localModify_` combinators to `Register`.+* Added `IF_S`, `LAM_S` and `LET_S` to `Defunc`, which can be used with overloaded syntax+* Admin: Removed `idioms-plugin` and `lift-plugin` from the test suite, depending on `parsley-garnish` instead+* Fixed building with GHC 9 -## 2.0.0.0 -- 2021-11-24+## 0.1.0.1 -- 2021-05-22 -* Incorporated API naming conventions from _Design Patterns for Parser Combinators_.- * `chainPre` -> `prefix`- * `chainPost` -> `postfix`- * `chainl1'` -> `infixl1`- * `chainr1'` -> `infixr1`- * `pfoldr` -> `manyr`- * `pfoldl` -> `manyl`- * `pfoldr1` -> `somer`- * `pfoldl1` -> `somel`-* Reworked the `precedence` combinator system in line with the paper: the horrible overloading- has gone now!-* Added in the `ParserOps` and `Debug` modules.-* Added `RANGES` to the `Defunc` API.-* Renamed `runParser` to `parse`.-* Moved some functionality to `Parsley.Char`.-* Added `digit`, `letter`, and `letterOrDigit`.+* Moved tests and benchmarks into a subproject, which will be easier later down the line.+* Removed useless `dump-core` flag (only used by test and bench, not by the library).+* Fleshed out README properly!++## 0.1.0.0 -- 2021-05-22++* First version. Released on an unsuspecting world.
− benchmarks/BrainfuckBench/Attoparsec/Parser.hs
@@ -1,17 +0,0 @@-module BrainfuckBench.Attoparsec.Parser where--import Shared.Attoparsec.Extended-import BrainfuckBench.Shared--brainfuck :: Parser [BrainFuckOp]-brainfuck = whitespace *> bf <* endOfInput- where- bf = many ( lexeme (char '>' $> RightPointer)- <|> lexeme (char '<' $> LeftPointer)- <|> lexeme (char '+' $> Increment)- <|> lexeme (char '-' $> Decrement)- <|> lexeme (char '.' $> Output)- <|> lexeme (char ',' $> Input)- <|> between (lexeme (char '[')) (lexeme (char ']')) (Loop <$> bf))- whitespace = skipMany (noneOf "<>+-.,[]")- lexeme p = p <* whitespace
− benchmarks/BrainfuckBench/Handrolled/Parser.hs
@@ -1,26 +0,0 @@-module BrainfuckBench.Handrolled.Parser where-import BrainfuckBench.Shared--brainfuck :: String -> Maybe [BrainFuckOp]-brainfuck input =- let walk :: String -> [BrainFuckOp] -> Maybe ([BrainFuckOp], String)- walk [] acc = return (reverse acc, [])- walk input@(']':_) acc = return (reverse acc, input)- walk (c:rest) acc = case c of- '>' -> walk rest (RightPointer:acc)- '<' -> walk rest (LeftPointer:acc)- '+' -> walk rest (Increment:acc)- '-' -> walk rest (Decrement:acc)- '.' -> walk rest (Output:acc)- ',' -> walk rest (Input:acc)- '[' -> do (body, rest') <- loop rest; walk rest' (Loop body:acc)- _ -> walk rest acc- loop :: String -> Maybe ([BrainFuckOp], String)- loop input = do- (body, rest) <- walk input []- case rest of- ']':rest' -> return (body, rest')- _ -> fail "unclosed loop"- in do- (res, []) <- walk input []- return res
− benchmarks/BrainfuckBench/Happy/Parser.y
@@ -1,33 +0,0 @@-{-module BrainfuckBench.Happy.Parser where-import BrainfuckBench.Shared (BrainFuckOp(..))-}--%name brainfuck Bf-%tokentype { Char }-%error { const Nothing }-%monad { Maybe }--%token- inc { '+' }- dec { '-' }- out { '.' }- in { ',' }- lft { '<' }- rht { '>' }- lb { '[' }- rb { ']' }- ws { $$ }--%%--Bf :: { [BrainFuckOp] }-Bf : inc Bf { Increment : $2 }- | dec Bf { Decrement : $2 }- | out Bf { Output : $2 }- | in Bf { Input : $2 }- | lft Bf { LeftPointer : $2 }- | rht Bf { RightPointer : $2 }- | lb Bf rb Bf { Loop $2 : $4 }- | ws Bf { $2 }- | { [] }
− benchmarks/BrainfuckBench/Main.hs
@@ -1,66 +0,0 @@-{-# LANGUAGE TemplateHaskell,- ScopedTypeVariables,- StandaloneDeriving,- DeriveAnyClass,- DeriveGeneric,- TypeFamilies,- UnboxedTuples,- TypeApplications #-}-module Main where-import Criterion.Main (Benchmark, bgroup, defaultMain)-import Control.DeepSeq (NFData)-import GHC.Generics (Generic)-import Data.ByteString (ByteString)-import Parsley.InputExtras (CharList(..))-import Data.Text (Text)---import Parsley.Internal.Verbose ()-import qualified BrainfuckBench.Parsley.Parser-import qualified BrainfuckBench.Parsec.Parser-import qualified BrainfuckBench.Megaparsec.Parser-import qualified BrainfuckBench.Attoparsec.Parser-import qualified BrainfuckBench.Handrolled.Parser-import qualified BrainfuckBench.Happy.Parser-import qualified Parsley-import qualified Data.ByteString.Lazy-import BrainfuckBench.Shared-import Shared.BenchmarkUtils--main :: IO ()-main = defaultMain [brainfuck]--deriving instance Generic BrainFuckOp-deriving instance NFData BrainFuckOp--brainfuckParsleyS :: String -> Maybe [BrainFuckOp]-brainfuckParsleyS = $$(Parsley.parse BrainfuckBench.Parsley.Parser.brainfuck)--brainfuckParsleyT :: Text -> Maybe [BrainFuckOp]-brainfuckParsleyT = $$(Parsley.parse BrainfuckBench.Parsley.Parser.brainfuck)--brainfuckParsleyB :: ByteString -> Maybe [BrainFuckOp]-brainfuckParsleyB = $$(Parsley.parse BrainfuckBench.Parsley.Parser.brainfuck)--brainfuckParsleySS :: CharList -> Maybe [BrainFuckOp]-brainfuckParsleySS = $$(Parsley.parse BrainfuckBench.Parsley.Parser.brainfuck)--brainfuckParsleyLB :: Data.ByteString.Lazy.ByteString -> Maybe [BrainFuckOp]-brainfuckParsleyLB = $$(Parsley.parse BrainfuckBench.Parsley.Parser.brainfuck)--brainfuck :: Benchmark-brainfuck =- let bfTest :: NFData rep => (FilePath -> IO rep) -> String -> (rep -> Maybe [BrainFuckOp]) -> Benchmark- bfTest = benchmark ["benchmarks/inputs/helloworld.bf", "benchmarks/inputs/helloworld_golfed.bf", "benchmarks/inputs/compiler.bf"]- in bgroup "Brainfuck"- [ bfTest string "Parsley (CharList)" (brainfuckParsleySS . CharList)- , bfTest string "Parsley (String)" brainfuckParsleyS- , bfTest text "Parsley (Text)" brainfuckParsleyT- , bfTest bytestring "Parsley (ByteString)" brainfuckParsleyB- --, bfTest lazy_bytestring "Parsley (Lazy ByteString)" brainfuckParsleyLB- , bfTest string "Handrolled" BrainfuckBench.Handrolled.Parser.brainfuck- , bfTest string "Happy" BrainfuckBench.Happy.Parser.brainfuck- , bfTest string "Parsec (String)" (parsecParse BrainfuckBench.Parsec.Parser.brainfuck)- , bfTest text "Parsec (Text)" (parsecParse BrainfuckBench.Parsec.Parser.brainfuck)- , bfTest string "Mega (String)" (megaParse BrainfuckBench.Megaparsec.Parser.brainfuck)- , bfTest text "Mega (Text)" (megaParse BrainfuckBench.Megaparsec.Parser.brainfuck)- , bfTest text "Atto (Text)" (attoParse BrainfuckBench.Attoparsec.Parser.brainfuck)- ]
− benchmarks/BrainfuckBench/Megaparsec/Parser.hs
@@ -1,19 +0,0 @@-{-# LANGUAGE ScopedTypeVariables, TypeFamilies #-}-module BrainfuckBench.Megaparsec.Parser where--import Shared.Megaparsec.Extended-import BrainfuckBench.Shared--brainfuck :: forall s. (Stream s, Token s ~ Char) => Parser s [BrainFuckOp]-brainfuck = whitespace *> bf <* eof- where- bf = many ( lexeme (char '>' $> RightPointer)- <|> lexeme (char '<' $> LeftPointer)- <|> lexeme (char '+' $> Increment)- <|> lexeme (char '-' $> Decrement)- <|> lexeme (char '.' $> Output)- <|> lexeme (char ',' $> Input)- <|> between (lexeme (char '[')) (lexeme (char ']')) (Loop <$> bf))- whitespace = skipMany (noneOf "<>+-.,[]")- lexeme :: Parser s a -> Parser s a- lexeme p = p <* whitespace
− benchmarks/BrainfuckBench/Parsec/Parser.hs
@@ -1,18 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-module BrainfuckBench.Parsec.Parser where--import Shared.Parsec.Extended-import BrainfuckBench.Shared--brainfuck :: Stream s Identity Char => Parser s [BrainFuckOp]-brainfuck = whitespace *> bf <* eof- where- bf = many ( lexeme (char '>' $> RightPointer)- <|> lexeme (char '<' $> LeftPointer)- <|> lexeme (char '+' $> Increment)- <|> lexeme (char '-' $> Decrement)- <|> lexeme (char '.' $> Output)- <|> lexeme (char ',' $> Input)- <|> between (lexeme (char '[')) (lexeme (char ']')) (Loop <$> bf))- whitespace = skipMany (noneOf "<>+-.,[]")- lexeme p = p <* whitespace
− benchmarks/BrainfuckBench/Parsley/Parser.hs
@@ -1,67 +0,0 @@-{-# OPTIONS_GHC -fplugin=Parsley.OverloadedQuotesPlugin #-}-{-# LANGUAGE TemplateHaskellQuotes #-}-{-# LANGUAGE DeriveLift #-}-{-# LANGUAGE StandaloneDeriving #-}-module BrainfuckBench.Parsley.Parser where--import Prelude hiding (fmap, pure, (<*), (*>), (<*>), (<$>), (<$), pred)-import BrainfuckBench.Shared-import Parsley-import Parsley.Combinator (eof)-import Parsley.Char(noneOf)-import Parsley.Fold (skipMany)---import Parsley.Garnish-import Language.Haskell.TH.Syntax (Lift(..))--import Parsley.Register-import Parsley.Defunctionalized--deriving instance Lift BrainFuckOp--brainfuck :: Parser [BrainFuckOp]-brainfuck = whitespace *> bf <* eof- where- whitespace = skipMany (noneOf "<>+-[],.")- lexeme p = p <* whitespace- {-bf = many ( lexeme ((token ">" $> code RightPointer)- <|> (token "<" $> code LeftPointer)- <|> (token "+" $> code Increment)- <|> (token "-" $> code Decrement)- <|> (token "." $> code Output)- <|> (token "," $> code Input)- <|> (between (lexeme (token "[")) (token "]") (code Loop <$> bf))))-}- bf = many (lexeme (match "><+-.,[" (lookAhead item) op empty))- op '>' = item $> [|RightPointer|]- op '<' = item $> [|LeftPointer|]- op '+' = item $> [|Increment|]- op '-' = item $> [|Decrement|]- op '.' = item $> [|Output|]- op ',' = item $> [|Input|]- op '[' = between (lexeme item) (try (char ']')) ([|Loop|] <$> bf)---- This is as closed to the handrolled version as it's possible to get: it's /very/ fast--- If register elimination can be performed, this would be equivalent to the handrolled I think-brainfuck' :: Parser [BrainFuckOp]-brainfuck' = newRegister_ EMPTY $ \acc ->- let walk :: Parser [BrainFuckOp]- -- This `eof` is interesting- -- The "obvious" way of thinking about this is to just move that `gets_` clause last- -- This works because `item` only fails if `eof` wouldn't have done.- -- However, at the /moment/, Parsley knows that `eof`'s failure doesn't consume input, and- -- optimises the handlers appropriately, but the scope of the failure of the match covers- -- the cases too, and so failing there generates a length check etc. Interestingly, the fix- -- here is to add a `try` (!!!), which improves performance considerably (but GHC then decides- -- not to inline something to make them otherwise identical). That's wild.- walk = eof *> gets_ acc [|reverse|]- <|> lookAhead (char ']') *> gets_ acc [|reverse|]- <|> {- try ( -}match "><+-.,[" item op walk -- )- -- <|> gets_ acc [|reverse|]- op :: Char -> Parser [BrainFuckOp]- op '>' = modify_ acc (APP_H CONS (LIFTED RightPointer)) *> walk- op '<' = modify_ acc (APP_H CONS (LIFTED LeftPointer)) *> walk- op '+' = modify_ acc (APP_H CONS (LIFTED Increment)) *> walk- op '-' = modify_ acc (APP_H CONS (LIFTED Decrement)) *> walk- op '.' = modify_ acc (APP_H CONS (LIFTED Output)) *> walk- op ',' = modify_ acc (APP_H CONS (LIFTED Input)) *> walk- op '[' = modify acc (CONS <$> ([|Loop|] <$> local acc (pure EMPTY) (walk <* char ']'))) *> walk- in walk <* eof
@@ -1,35 +0,0 @@-module BrainfuckBench.Shared where-import Data.Int-import Data.Char (ord, chr)--data BrainFuckOp = RightPointer | LeftPointer | Increment | Decrement | Output | Input | Loop [BrainFuckOp] deriving Show--data Tape a = Tape [a] a [a]--evalBf :: [BrainFuckOp] -> IO ()-evalBf prog = go (Tape (repeat 0) 0 (repeat 0)) prog >> return ()- where- evalOp :: BrainFuckOp -> Tape Int32 -> IO (Tape Int32)- evalOp RightPointer tape = return (right tape)- evalOp LeftPointer tape = return (left tape)- evalOp Increment tape = let x = read tape in return (write (succ x) tape)- evalOp Decrement tape = let x = read tape in return (write (pred x) tape)- evalOp Output tape = let x = read tape in do print (chr (fromEnum x)); return tape- evalOp Input tape = do x <- getChar; return (write (toEnum (ord x)) tape)- evalOp (Loop p) tape = let x = read tape in if x == 0 then return tape- else do tape' <- go tape p- if read tape' /= 0 then evalOp (Loop p) tape'- else return tape'-- go :: Tape Int32 -> [BrainFuckOp] -> IO (Tape Int32)- go tape [] = return tape- go tape (op:ops) = do tape' <- evalOp op tape; go tape' ops-- right :: Tape a -> Tape a- right (Tape ls x (r:rs)) = Tape (x:ls) r rs- left :: Tape a -> Tape a- left (Tape (l:ls) x rs) = Tape ls l (x:rs)- read :: Tape a -> a- read (Tape _ x _) = x- write :: a -> Tape a -> Tape a- write x (Tape ls _ rs) = Tape ls x rs
− benchmarks/JavascriptBench/Attoparsec/Parser.hs
@@ -1,242 +0,0 @@-module JavascriptBench.Attoparsec.Parser where--import Shared.Attoparsec.Extended-import JavascriptBench.Shared--import Data.Char (isSpace, isUpper, digitToInt)-import Data.Maybe (catMaybes)-import Text.Read (readMaybe)--javascript :: Parser JSProgram-javascript = whitespace *> many element <* endOfInput- where- element :: Parser JSElement- element = keyword "function" *> liftA3 JSFunction identifier (parens (commaSep identifier)) compound- <|> JSStm <$> stmt- compound :: Parser JSCompoundStm- compound = braces (many stmt)- stmt :: Parser JSStm- stmt = semi $> JSSemi- <|> keyword "if" *> liftA3 JSIf parensExpr stmt (maybeP (keyword "else" *> stmt))- <|> keyword "while" *> liftA2 JSWhile parensExpr stmt- <|> (keyword "for" *> parens- (try (liftA2 JSForIn varsOrExprs (keyword "in" *> expr))- <|> liftA3 JSFor (maybeP varsOrExprs <* semi) (optExpr <* semi) optExpr)- <*> stmt)- <|> keyword "break" $> JSBreak- <|> keyword "continue" $> JSContinue- <|> keyword "with" *> liftA2 JSWith parensExpr stmt- <|> keyword "return" *> (JSReturn <$> optExpr)- <|> JSBlock <$> compound- <|> JSNaked <$> varsOrExprs- varsOrExprs :: Parser (Either [JSVar] JSExpr)- varsOrExprs = (keyword "var" *> commaSep1 variable) <+> expr- variable :: Parser JSVar- variable = liftA2 JSVar identifier (maybeP (symbol '=' *> asgn))- parensExpr :: Parser JSExpr- parensExpr = parens expr- optExpr :: Parser (Maybe JSExpr)- optExpr = maybeP expr- expr :: Parser JSExpr- expr = commaSep1 asgn- asgn :: Parser JSExpr'- asgn = chainl1 condExpr (symbol '=' $> JSAsgn)- condExpr :: Parser JSExpr'- condExpr = liftA2 jsCondExprBuild expr' (maybeP ((symbol '?' *> asgn) <~> (symbol ':' *> asgn)))- expr' :: Parser JSExpr'- expr' = precedence- [ Prefix [ operator "--" $> jsDec, operator "++" $> jsInc- , operator "-" $> jsNeg, operator "+" $> jsPlus- , operator "~" $> jsBitNeg, operator "!" $> jsNot ]- , Postfix [ operator "--" $> jsDec, operator "++" $> jsInc ]- , InfixL [ operator "*" $> JSMul, operator "/" $> JSDiv- , operator "%" $> JSMod ]- , InfixL [ operator "+" $> JSAdd, operator "-" $> JSSub ]- , InfixL [ operator "<<" $> JSShl, operator ">>" $> JSShr ]- , InfixL [ operator "<=" $> JSLe, operator "<" $> JSLt- , operator ">=" $> JSGe, operator ">" $> JSGt ]- , InfixL [ operator "==" $> JSEq, operator "!=" $> JSNe ]- , InfixL [ try (operator "&") $> JSBitAnd ]- , InfixL [ operator "^" $> JSBitXor ]- , InfixL [ try (operator "|") $> JSBitOr ]- , InfixL [ operator "&&" $> JSAnd ]- , InfixL [ operator "||" $> JSOr ]- ]- (JSUnary <$> memOrCon)- memOrCon :: Parser JSUnary- memOrCon = keyword "delete" *> (JSDel <$> member)- <|> keyword "new" *> (JSCons <$> con)- <|> JSMember <$> member- con :: Parser JSCons- con = liftA2 JSQual (keyword "this" $> "this") (dot *> conCall) <|> conCall- conCall :: Parser JSCons- conCall = identifier <**>- (dot *> (flip JSQual <$> conCall)- <|> flip JSConCall <$> parens (commaSep asgn)- <|> pure (\name -> JSConCall name []))- member :: Parser JSMember- member = primaryExpr <**>- (flip JSCall <$> parens (commaSep asgn)- <|> flip JSIndex <$> brackets expr- <|> dot *> ((flip JSAccess) <$> member)- <|> pure JSPrimExp)- primaryExpr :: Parser JSAtom- primaryExpr = JSParens <$> parens expr- <|> JSArray <$> brackets (commaSep asgn)- <|> JSId <$> identifier- <|> either JSInt JSFloat <$> naturalOrFloat- <|> JSString <$> stringLiteral- <|> JSTrue <$ keyword "true"- <|> JSFalse <$ keyword "false"- <|> JSNull <$ keyword "null"- <|> JSThis <$ keyword "this"-- -- Token Parsers- space :: Parser ()- space = void (satisfy isSpace)- whitespace :: Parser ()- whitespace = skipMany (spaces <|> oneLineComment <|> multiLineComment)- keyword :: String -> Parser ()- keyword s = try (string s *> notIdentLetter) *> whitespace- operator :: String -> Parser ()- operator op = try (string op *> notOpLetter) *> whitespace- identifier :: Parser String- identifier = try ((identStart <:> many identLetter) >?> jsUnreservedName) <* whitespace- naturalOrFloat :: Parser (Either Int Double)- naturalOrFloat = natFloat <* whitespace-- -- Nonsense to deal with floats and ints- natFloat :: Parser (Either Int Double)- natFloat = char '0' *> zeroNumFloat <|> decimalFloat-- zeroNumFloat :: Parser (Either Int Double)- zeroNumFloat = Left <$> (hexadecimal <|> octal)- <|> decimalFloat- <|> (fromMaybeP (fractFloat <*> pure 0) empty)- <|> pure (Left 0)-- decimalFloat :: Parser (Either Int Double)- decimalFloat = fromMaybeP (decimal <**> (option (Just . Left) fractFloat)) empty-- fractFloat :: Parser (Int -> Maybe (Either Int Double))- fractFloat = f <$> fractExponent- where- f g x = fmap Right (g x)-- fractExponent :: Parser (Int -> Maybe Double)- fractExponent = f <$> fraction <*> option "" exponent'- <|> f <$> pure "" <*> exponent'- where- f fract exp n = readMaybe (show n ++ fract ++ exp)-- fraction :: Parser [Char]- fraction = char '.' <:> some (oneOf ['0'..'9'])-- exponent' :: Parser [Char]- exponent' = ('e' :) <$> (oneOf "eE"- *> ((((:) <$> oneOf "+-") <|> pure id)- <*> (show <$> decimal)))-- decimal :: Parser Int- decimal = number 10 (oneOf ['0'..'9'])- hexadecimal = oneOf "xX" *> number 16 (oneOf (['a'..'f'] ++ ['A'..'F'] ++ ['0'..'9']))- octal = oneOf "oO" *> number 8 (oneOf ['0'..'7'])-- number :: Int -> Parser Char -> Parser Int- number base = pfoldl1 (\x d -> base * x + digitToInt d) 0-- stringLiteral :: Parser String- stringLiteral = catMaybes <$> between (token "\"") (token "\"") (many stringChar) <* whitespace- symbol :: Char -> Parser Char- symbol c = try (char c) <* whitespace- parens :: Parser a -> Parser a- parens = between (symbol '(') (symbol ')')- brackets :: Parser a -> Parser a- brackets = between (symbol '[') (symbol ']')- braces :: Parser a -> Parser a- braces = between (symbol '{') (symbol '}')- dot :: Parser Char- dot = symbol '.'- semi :: Parser Char- semi = symbol ';'- comma :: Parser Char- comma = symbol ','- commaSep :: Parser a -> Parser [a]- commaSep p = sepBy p comma- commaSep1 :: Parser a -> Parser [a]- commaSep1 p = sepBy1 p comma-- -- Let bindings- spaces :: Parser ()- spaces = skipSome space-- oneLineComment :: Parser ()- oneLineComment = void (token "//" *> skipMany (satisfy (/= '\n')))-- multiLineComment :: Parser ()- multiLineComment =- let inComment = void (token "*/")- <|> skipSome (satisfy (/= '*')) *> inComment- <|> char '*' *> inComment- in token "/*" *> inComment-- identStart = satisfy jsIdentStart- identLetter = satisfy jsIdentLetter- notIdentLetter = peekChar >?> (maybe True (not . jsIdentLetter))- notOpLetter = peekChar >?> (maybe True (notInClass "+-*/=<>!~&|.%^"))-- escChrs :: [Char]- escChrs = "abfntv\\\"'0123456789xo^ABCDEFGHLNRSUV"-- stringChar :: Parser (Maybe Char)- stringChar = Just <$> satisfy jsStringLetter <|> stringEscape-- stringEscape :: Parser (Maybe Char)- stringEscape = token "\\" *> (token "&" $> Nothing- <|> spaces *> token "\\" $> Nothing- <|> Just <$> escapeCode)-- escapeCode :: Parser Char- escapeCode = match escChrs (oneOf escChrs) escCode empty- where- escCode 'a' = pure ('\a')- escCode 'b' = pure ('\b')- escCode 'f' = pure ('\f')- escCode 'n' = pure ('\n')- escCode 't' = pure ('\t')- escCode 'v' = pure ('\v')- escCode '\\' = pure ('\\')- escCode '"' = pure ('"')- escCode '\'' = pure ('\'')- escCode '^' = (\c -> toEnum (fromEnum c - fromEnum 'A' + 1)) <$> satisfy isUpper- escCode 'A' = token "CK" $> ('\ACK')- escCode 'B' = token "S" $> ('\BS') <|> token "EL" $> ('\BEL')- escCode 'C' = token "R" $> ('\CR') <|> token "AN" $> ('\CAN')- escCode 'D' = token "C" *> (token "1" $> ('\DC1')- <|> token "2" $> ('\DC2')- <|> token "3" $> ('\DC3')- <|> token "4" $> ('\DC4'))- <|> token "EL" $> ('\DEL')- <|> token "LE" $> ('\DLE')- escCode 'E' = token "M" $> ('\EM')- <|> token "T" *> (token "X" $> ('\ETX')- <|> token "B" $> ('\ETB'))- <|> token "SC" $> ('\ESC')- <|> token "OT" $> ('\EOT')- <|> token "NQ" $> ('\ENQ')- escCode 'F' = token "F" $> ('\FF') <|> token "S" $> ('\FS')- escCode 'G' = token "S" $> ('\GS')- escCode 'H' = token "T" $> ('\HT')- escCode 'L' = token "F" $> ('\LF')- escCode 'N' = token "UL" $> ('\NUL') <|> token "AK" $> ('\NAK')- escCode 'R' = token "S" $> ('\RS')- escCode 'S' = token "O" *> option (('\SO')) (token "H" $> ('\SOH'))- <|> token "I" $> ('\SI')- <|> token "P" $> ('\SP')- <|> token "TX" $> ('\STX')- <|> token "YN" $> ('\SYN')- <|> token "UB" $> ('\SUB')- escCode 'U' = token "S" $> ('\US')- escCode 'V' = token "T" $> ('\VT')- -- TODO numeric- escCode _ = empty--error "numeric escape codes not supported"
− benchmarks/JavascriptBench/Happy/Parser.y
@@ -1,466 +0,0 @@-{-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-module JavascriptBench.Happy.Parser where-import JavascriptBench.Shared-import Control.Monad.Reader-import Control.Applicative-import Data.Char (isSpace, isAlpha, isDigit, isAlphaNum, isUpper, isHexDigit, isOctDigit)-import Data.Maybe (fromMaybe)-import Data.List (span)-import Text.Read (readMaybe)-}--%name javascript Program-%lexer { lexer } { Eof }-%tokentype { Token }-%error { failParse }-%monad { Parser }--%token- number { TokenNumber $$ }- id { TokenId $$ }- true { TokenTrue }- false { TokenFalse }- if { TokenIf }- else { TokenElse }- for { TokenFor }- while { TokenWhile }- with { TokenWith }- break { TokenBreak }- continue { TokenContinue }- function { TokenFunction }- var { TokenVar }- new { TokenNew }- delete { TokenDelete }- this { TokenThis }- null { TokenNull }- return { TokenReturn }- in { TokenIn }- '=' { TokenAss }- ':' { TokenColon }- '?' { TokenQuest }- '--' { TokenDec }- '++' { TokenInc }- '+' { TokenAdd }- '-' { TokenSub }- '!' { TokenNot }- '~' { TokenNeg }- '*' { TokenMul }- '/' { TokenDiv }- '%' { TokenMod }- '<<' { TokenShl }- '>>' { TokenShr }- '<=' { TokenLeq }- '<' { TokenLt }- '>=' { TokenGeq }- '>' { TokenGt }- '==' { TokenEq }- '!=' { TokenNeq }- '&' { TokenBAnd }- '|' { TokenBOr }- '^' { TokenXor }- '&&' { TokenAnd }- '||' { TokenOr }- string { TokenString $$ }- '(' { TokenLParen }- ')' { TokenRParen }- '[' { TokenLBracket }- ']' { TokenRBracket }- '{' { TokenLBrace }- '}' { TokenRBrace }- '.' { TokenDot }- ';' { TokenSemi }- ',' { TokenComma }-%%--Program :: { JSProgram }-Program : Element Program { $1 : $2 }- | { [] }--Element :: { JSElement }-Element : function id '(' Params ')' Compound { JSFunction $2 $4 $6 }- | Stmt { JSStm $1 }--Params :: { [String] }-Params : id ',' Params { $1 : $3 }- | id { [$1] }- | { [] }--Compound :: { JSCompoundStm }-Compound : '{' Compound_ '}' { $2 }--Compound_ :: { [JSStm] }-Compound_ : Stmt Compound_ { $1 : $2 }- | { [] }--Stmt :: { JSStm }-Stmt : ';' { JSSemi }- | if '(' Expr ')' Stmt Else { JSIf $3 $5 $6 }- | while '(' Expr ')' Stmt { JSWhile $3 $5 }- | for '(' VarsOrExprs in Expr ')' Stmt { JSForIn $3 $5 $7 }- | for '(' OptVarsOrExprs ';' OptExpr ';' OptExpr ')' Stmt { JSFor $3 $5 $7 $9}- | break { JSBreak }- | continue { JSContinue }- | with '(' Expr ')' Stmt { JSWith $3 $5 }- | return OptExpr { JSReturn $2 }- | Compound { JSBlock $1 }- | VarsOrExprs { JSNaked $1 }--Else :: { Maybe JSStm }-Else : else Stmt { Just $2 }- | { Nothing }--OptExpr :: { Maybe JSExpr }-OptExpr : Expr { Just $1 }- | { Nothing }--OptVarsOrExprs :: { Maybe (Either [JSVar] JSExpr) }-OptVarsOrExprs : VarsOrExprs { Just $1 }- | { Nothing }--VarsOrExprs :: { Either [JSVar] JSExpr }-VarsOrExprs : var Vars { Left $2 }- | Expr { Right $1 }--Vars :: { [JSVar] }-Vars : Variable ',' Vars { $1 : $3 }- | Variable { [$1] }--Variable :: { JSVar }-Variable : id '=' Asgn { JSVar $1 (Just $3) }- | id { JSVar $1 Nothing }--Expr :: { JSExpr }-Expr : Asgn ',' Expr { $1 : $3 }- | Asgn { [$1] }--Asgn :: { JSExpr' }-Asgn : Asgn '=' CondExpr { JSAsgn $1 $3 }- | CondExpr { $1 }--CondExpr :: { JSExpr' }-CondExpr : OrExpr Ternary { jsCondExprBuild $1 $2 }--Ternary :: { Maybe (JSExpr', JSExpr') }-Ternary : '?' Asgn ':' Asgn { Just ($2, $4) }- | { Nothing }---- Expressions-OrExpr :: { JSExpr' }-OrExpr : OrExpr '||' AndExpr { JSOr $1 $3 } | AndExpr { $1 }-AndExpr : AndExpr '&&' BitOrExpr { JSAnd $1 $3 } | BitOrExpr { $1 }-BitOrExpr : BitOrExpr '|' BitXorExpr { JSBitOr $1 $3 } | BitXorExpr { $1 }-BitXorExpr : BitXorExpr '^' BitAndExpr { JSBitXor $1 $3 } | BitAndExpr { $1 }-BitAndExpr : BitAndExpr '&' EqExpr { JSBitAnd $1 $3 } | EqExpr { $1 }-EqExpr : EqExpr '==' CompExpr { JSEq $1 $3 }- | EqExpr '!=' CompExpr { JSNe $1 $3 }- | CompExpr { $1 }-CompExpr : CompExpr '<=' ShiftExpr { JSLe $1 $3 }- | CompExpr '<' ShiftExpr { JSLt $1 $3 }- | CompExpr '>=' ShiftExpr { JSGe $1 $3 }- | CompExpr '>' ShiftExpr { JSGt $1 $3 }- | ShiftExpr { $1 }-ShiftExpr : ShiftExpr '<<' WeakArithExpr { JSShl $1 $3 }- | ShiftExpr '>>' WeakArithExpr { JSShr $1 $3 }- | WeakArithExpr { $1 }-WeakArithExpr : WeakArithExpr '+' StrongArithExpr { JSAdd $1 $3 }- | WeakArithExpr '-' StrongArithExpr { JSSub $1 $3 }- | StrongArithExpr { $1 }-StrongArithExpr : StrongArithExpr '*' Postfixes { JSMul $1 $3 }- | StrongArithExpr '/' Postfixes { JSDiv $1 $3 }- | StrongArithExpr '%' Postfixes { JSMod $1 $3 }- | Postfixes { $1 }-Postfixes : Postfixes '--' { jsDec $1 }- | Postfixes '++' { jsInc $1 }- | Prefixes { $1 }-Prefixes : '--' Prefixes { jsDec $2 }- | '++' Prefixes { jsInc $2 }- | '-' Prefixes { jsNeg $2 }- | '+' Prefixes { jsPlus $2 }- | '~' Prefixes { jsBitNeg $2 }- | '!' Prefixes { jsNot $2 }- | MemOrCon { JSUnary $1 }--MemOrCon :: { JSUnary }-MemOrCon : delete Member { JSDel $2 }- | new Con { JSCons $2 }- | Member { JSMember $1 }--Con :: { JSCons }-Con : this '.' ConCall { JSQual "this" $3 }- | ConCall { $1 }--ConCall :: { JSCons }-ConCall : id ConCall_ { $2 $1 }--ConCall_ :: { String -> JSCons }-ConCall_ : '.' ConCall { flip JSQual $2 }- | '(' CommaAsgn ')' { flip JSConCall $2 }- | { flip JSConCall [] }--CommaAsgn :: { [JSExpr'] }-CommaAsgn : Expr { $1 }- | { [] }--Member :: { JSMember }-Member : PrimaryExpr Member_ { $2 $1 }--Member_ :: { JSAtom -> JSMember }-Member_ : '(' CommaAsgn ')' { flip JSCall $2 }- | '[' Expr ']' { flip JSIndex $2 }- | '.' Member { flip JSAccess $2 }- | { JSPrimExp }--PrimaryExpr :: { JSAtom }-PrimaryExpr : '(' Expr ')' { JSParens $2 }- | '[' CommaAsgn ']' { JSArray $2 }- | id { JSId $1 }- | number { either JSInt JSFloat $1 }- | string { JSString $1 }- | true { JSTrue }- | false { JSFalse }- | null { JSNull }- | this { JSThis }--{-data Token = TokenNumber (Either Int Double)- | TokenId String- | TokenTrue- | TokenFalse- | TokenIf- | TokenElse- | TokenFor- | TokenWhile- | TokenWith- | TokenBreak- | TokenContinue- | TokenFunction- | TokenVar- | TokenNew- | TokenDelete- | TokenThis- | TokenNull- | TokenReturn- | TokenIn- | TokenAss- | TokenColon- | TokenQuest- | TokenDec- | TokenInc- | TokenAdd- | TokenSub- | TokenNot- | TokenNeg- | TokenMul- | TokenDiv- | TokenMod- | TokenShl- | TokenShr- | TokenLeq- | TokenLt- | TokenGeq- | TokenGt- | TokenEq- | TokenNeq- | TokenBAnd- | TokenBOr- | TokenXor- | TokenAnd- | TokenOr- | TokenString String- | TokenLParen- | TokenRParen- | TokenLBracket- | TokenRBracket- | TokenLBrace- | TokenRBrace- | TokenDot- | TokenSemi- | TokenComma- | Eof--newtype Parser a = Parser (ReaderT String Maybe a)- deriving (Functor, Applicative, Alternative, Monad, MonadReader String)--failParse :: Token -> Parser a-failParse _ = Parser empty--runParser :: Parser a -> String -> Maybe a-runParser (Parser p) = runReaderT p--lexer :: (Token -> Parser a) -> Parser a-lexer k = do- input <- ask- case whiteSpace input of- [] -> k Eof- c:cs -> nextToken c cs (\t input -> local (const input) (k t))- where- nextToken :: Char -> String -> (Token -> String -> Parser a) -> Parser a- nextToken ';' cs k = k TokenSemi cs- nextToken ':' cs k = k TokenColon cs- nextToken '.' cs k = k TokenDot cs- nextToken ',' cs k = k TokenComma cs- nextToken '?' cs k = k TokenQuest cs- nextToken '(' cs k = k TokenLParen cs- nextToken ')' cs k = k TokenRParen cs- nextToken '[' cs k = k TokenLBracket cs- nextToken ']' cs k = k TokenRBracket cs- nextToken '{' cs k = k TokenLBrace cs- nextToken '}' cs k = k TokenRBrace cs- nextToken '*' cs k = k TokenMul cs- nextToken '/' cs k = k TokenDiv cs- nextToken '%' cs k = k TokenMod cs- nextToken '~' cs k = k TokenNeg cs- nextToken '!' ('=':cs) k = k TokenNeq cs- nextToken '!' cs k = k TokenNot cs- nextToken '=' ('=':cs) k = k TokenEq cs- nextToken '=' cs k = k TokenAss cs- nextToken '&' ('&':cs) k = k TokenAnd cs- nextToken '&' cs k = k TokenBAnd cs- nextToken '|' ('|':cs) k = k TokenOr cs- nextToken '|' cs k = k TokenBOr cs- nextToken '^' cs k = k TokenXor cs- nextToken '<' ('<':cs) k = k TokenShl cs- nextToken '<' ('=':cs) k = k TokenLeq cs- nextToken '<' cs k = k TokenLt cs- nextToken '>' ('>':cs) k = k TokenShr cs- nextToken '>' ('=':cs) k = k TokenGeq cs- nextToken '>' cs k = k TokenGt cs- nextToken '-' ('-':cs) k = k TokenDec cs- nextToken '-' cs k = k TokenSub cs- nextToken '+' ('+':cs) k = k TokenInc cs- nextToken '+' cs k = k TokenAdd cs- nextToken '"' cs k = stringLit cs (k . TokenString)- nextToken c cs k | isDigit c = numLit c cs (k . TokenNumber)- nextToken 'b' ('r':'e':'a':'k':cs) k | noIdLetter cs = k TokenBreak cs- nextToken 'c' ('o':'n':'t':'i':'n':'u':'e':cs) k | noIdLetter cs = k TokenContinue cs- nextToken 'd' ('e':'l':'e':'t':'e':cs) k | noIdLetter cs = k TokenDelete cs- nextToken 'e' ('l':'s':'e':cs) k | noIdLetter cs = k TokenElse cs- nextToken 'f' ('a':'l':'s':'e':cs) k | noIdLetter cs = k TokenFalse cs- nextToken 'f' ('o':'r':cs) k | noIdLetter cs = k TokenFor cs- nextToken 'f' ('u':'n':'c':'t':'i':'o':'n':cs) k | noIdLetter cs = k TokenFunction cs- nextToken 'i' ('f':cs) k | noIdLetter cs = k TokenIf cs- nextToken 'i' ('n':cs) k | noIdLetter cs = k TokenIn cs- nextToken 'n' ('e':'w':cs) k | noIdLetter cs = k TokenNew cs- nextToken 'n' ('u':'l':'l':cs) k | noIdLetter cs = k TokenNull cs- nextToken 'r' ('e':'t':'u':'r':'n':cs) k | noIdLetter cs = k TokenReturn cs- nextToken 't' ('h':'i':'s':cs) k | noIdLetter cs = k TokenThis cs- nextToken 't' ('r':'u':'e':cs) k | noIdLetter cs = k TokenTrue cs- nextToken 'v' ('a':'r':cs) k | noIdLetter cs = k TokenVar cs- nextToken 'w' ('h':'i':'l':'e':cs) k | noIdLetter cs = k TokenWhile cs- nextToken 'w' ('i':'t':'h':cs) k | noIdLetter cs = k TokenWith cs- nextToken c cs k | idLetter c = let (ident, rest) = span idLetter cs in k (TokenId (c:ident)) rest- nextToken c cs k = empty-- idLetter :: Char -> Bool- idLetter '_' = True- idLetter c = isAlphaNum c-- noIdLetter :: String -> Bool- noIdLetter (c:_) | idLetter c = False- noIdLetter _ = True-- numLit :: Char -> String -> (Either Int Double -> String -> Parser a) -> Parser a- numLit '0' = zeroNumFloat- numLit d = (fromMaybe empty .) . decimalFloat . (d :)-- zeroNumFloat :: String -> (Either Int Double -> String -> Parser a) -> Parser a- zeroNumFloat ('x':cs) k = hexadecimal cs (k . Left)- zeroNumFloat ('X':cs) k = hexadecimal cs (k . Left)- zeroNumFloat ('o':cs) k = octal cs (k . Left)- zeroNumFloat ('O':cs) k = octal cs (k . Left)- zeroNumFloat cs k = fromMaybe (k (Left 0) cs) (fractFloat 0 cs k <|> decimalFloat cs k)-- decimalFloat :: String -> (Either Int Double -> String -> Parser a) -> Maybe (Parser a)- decimalFloat (d:cs) k | isDigit d = return (decimal (d:cs) (\x cs -> fromMaybe (k (Left x) cs) (fractFloat x cs k)))- decimalFloat _ _ = empty-- fractFloat :: Int -> String -> (Either Int Double -> String -> Parser a) -> Maybe (Parser a)- fractFloat x ('.':cs) = fractExpMaker ('.':) x cs- fractFloat x ('e':cs) = exponent x cs- fractFloat x ('E':cs) = exponent x cs- fractFloat x cs = return Nothing-- exponent :: Int -> String -> (Either Int Double -> String -> Parser a) -> Maybe (Parser a)- exponent x ('+':cs) = fractExpMaker ('e':) x cs- exponent x ('-':cs) = fractExpMaker (('e':) . ('-':)) x cs- exponent x cs = fractExpMaker ('e':) x cs-- fractExpMaker :: (String -> String) -> Int -> String -> (Either Int Double -> String -> Parser a) -> Maybe (Parser a)- fractExpMaker conv x cs k = let (y, rest) = span isDigit cs in fmap (flip k rest . Right) (readMaybe (show x ++ conv y))-- number :: (Char -> Bool) -> (String -> String) -> String -> (Int -> String -> Parser a) -> Parser a- number digit conv cs k = let (x, rest) = span digit cs in maybe empty (flip k rest) (readMaybe (conv x))- decimal = number isDigit id- hexadecimal = number isHexDigit ("0x" ++)- octal = number isOctDigit ("0o" ++)-- stringLit :: String -> (String -> String -> Parser a) -> Parser a- stringLit = go id- where- go :: (String -> String) -> String -> (String -> String -> Parser a) -> Parser a- go acc ('\\':cs) k = escape cs (\c cs -> go (acc . (c:)) cs k)- go acc ('"':cs) k = k (acc []) cs- go acc (c:cs) k = go (acc . (c:)) cs k- go acc _ k = empty-- escape :: String -> (Char -> String -> Parser a) -> Parser a- escape ('a':cs) k = k '\a' cs- escape ('b':cs) k = k '\b' cs- escape ('f':cs) k = k '\f' cs- escape ('n':cs) k = k '\n' cs- escape ('t':cs) k = k '\t' cs- escape ('v':cs) k = k '\v' cs- escape ('\\':cs) k = k '\\' cs- escape ('"':cs) k = k '"' cs- escape ('\'':cs) k = k '\'' cs- escape ('^':c:cs) k | isUpper c = k (toEnum (fromEnum c - fromEnum 'A' + 1)) cs- escape ('A':'C':'K':cs) k = k '\ACK' cs- escape ('B':'S':cs) k = k '\BS' cs- escape ('B':'E':'L':cs) k = k '\BEL' cs- escape ('C':'R':cs) k = k '\CR' cs- escape ('C':'A':'N':cs) k = k '\CAN' cs- escape ('D':'C':'1':cs) k = k '\DC1' cs- escape ('D':'C':'2':cs) k = k '\DC2' cs- escape ('D':'C':'3':cs) k = k '\DC3' cs- escape ('D':'C':'4':cs) k = k '\DC4' cs- escape ('D':'E':'L':cs) k = k '\DEL' cs- escape ('D':'L':'E':cs) k = k '\DLE' cs- escape ('E':'M':cs) k = k '\EM' cs- escape ('E':'T':'X':cs) k = k '\ETX' cs- escape ('E':'T':'B':cs) k = k '\ETB' cs- escape ('E':'S':'C':cs) k = k '\ESC' cs- escape ('E':'O':'T':cs) k = k '\EOT' cs- escape ('E':'N':'Q':cs) k = k '\ENQ' cs- escape ('F':'F':cs) k = k '\FF' cs- escape ('F':'S':cs) k = k '\FS' cs- escape ('G':'S':cs) k = k '\GS' cs- escape ('H':'T':cs) k = k '\HT' cs- escape ('L':'F':cs) k = k '\LF' cs- escape ('N':'U':'L':cs) k = k '\NUL' cs- escape ('N':'A':'K':cs) k = k '\NAK' cs- escape ('R':'S':cs) k = k '\RS' cs- escape ('S':'O':'H':cs) k = k '\SOH' cs- escape ('S':'O':cs) k = k '\SO' cs- escape ('S':'I':cs) k = k '\SI' cs- escape ('S':'P':cs) k = k '\SP' cs- escape ('S':'T':'X':cs) k = k '\STX' cs- escape ('S':'Y':'N':cs) k = k '\SYN' cs- escape ('S':'U':'B':cs) k = k '\SUB' cs- escape ('U':'S':cs) k = k '\US' cs- escape ('V':'T':cs) k = k '\VT' cs- escape _ _ = empty-- whiteSpace :: String -> String- whiteSpace (c:cs) | isSpace c = whiteSpace cs- whiteSpace ('/':'*':cs) = multiLineComment cs- whiteSpace ('/':'/':cs) = singleLineComment cs- whiteSpace cs = cs- singleLineComment :: String -> String- singleLineComment = whiteSpace . dropWhile (/= '\n')- multiLineComment :: String -> String- multiLineComment ('*':'/':cs) = whiteSpace cs- multiLineComment (_:cs) = multiLineComment cs- multiLineComment [] = empty--}
− benchmarks/JavascriptBench/Main.hs
@@ -1,63 +0,0 @@-{-# LANGUAGE TemplateHaskell,- ScopedTypeVariables,- StandaloneDeriving,- DeriveAnyClass,- DeriveGeneric,- TypeFamilies,- UnboxedTuples,- TypeApplications #-}-module Main where-import Criterion.Main (Benchmark, bgroup, defaultMain)-import Control.DeepSeq (NFData)-import GHC.Generics (Generic)-import Data.Text (Text)---import Parsley.Internal.Verbose ()-import qualified JavascriptBench.Parsley.Parser-import qualified JavascriptBench.Parsec.Parser-import qualified JavascriptBench.Megaparsec.Parser-import qualified JavascriptBench.Attoparsec.Parser-import qualified JavascriptBench.Happy.Parser-import qualified Parsley-import JavascriptBench.Shared-import Shared.BenchmarkUtils--main :: IO ()-main = defaultMain [javascript]--deriving instance Generic JSElement-deriving instance Generic JSStm-deriving instance Generic JSVar-deriving instance Generic JSExpr'-deriving instance Generic JSUnary-deriving instance Generic JSMember-deriving instance Generic JSCons-deriving instance Generic JSAtom-deriving instance NFData JSElement-deriving instance NFData JSStm-deriving instance NFData JSVar-deriving instance NFData JSExpr'-deriving instance NFData JSUnary-deriving instance NFData JSMember-deriving instance NFData JSCons-deriving instance NFData JSAtom--javascriptParsleyS :: String -> Maybe JSProgram-javascriptParsleyS = $$(Parsley.parse JavascriptBench.Parsley.Parser.javascript)--javascriptParsleyT :: Text -> Maybe JSProgram-javascriptParsleyT = $$(Parsley.parse JavascriptBench.Parsley.Parser.javascript)--javascript :: Benchmark-javascript =- let jsTest :: NFData rep => (FilePath -> IO rep) -> String -> (rep -> Maybe JSProgram) -> Benchmark- jsTest = benchmark ["benchmarks/inputs/fibonacci.js", "benchmarks/inputs/heapsort.js", "benchmarks/inputs/game.js", "benchmarks/inputs/big.js"]- in bgroup "Javascript"- [ jsTest text "Parsley (Text)" javascriptParsleyT- , jsTest string "Parsley (String)" javascriptParsleyS- , jsTest text "Atto" (attoParse JavascriptBench.Attoparsec.Parser.javascript)- , jsTest string "Happy" (JavascriptBench.Happy.Parser.runParser JavascriptBench.Happy.Parser.javascript)- , jsTest string "Parsec (String)" (parsecParse JavascriptBench.Parsec.Parser.javascript)- , jsTest text "Parsec (Text)" (parsecParse JavascriptBench.Parsec.Parser.javascript)- , jsTest string "Mega (String)" (megaParse JavascriptBench.Megaparsec.Parser.javascript)- , jsTest text "Mega (Text)" (megaParse JavascriptBench.Megaparsec.Parser.javascript)- ]
− benchmarks/JavascriptBench/Megaparsec/Parser.hs
@@ -1,244 +0,0 @@-{-# LANGUAGE TypeFamilies- , ScopedTypeVariables #-}--module JavascriptBench.Megaparsec.Parser where-import JavascriptBench.Shared-import Shared.Megaparsec.Extended-import Data.Char (isSpace, isUpper, digitToInt)-import Data.Maybe (catMaybes)-import Text.Read (readMaybe)--javascript :: forall s. (Stream s, Token s ~ Char) => Parser s JSProgram-javascript = whitespace *> many element <* eof- where- element :: Parser s JSElement- element = keyword "function" *> liftA3 JSFunction identifier (parens (commaSep identifier)) compound- <|> JSStm <$> stmt- compound :: Parser s JSCompoundStm- compound = braces (many stmt)- stmt :: Parser s JSStm- stmt = semi $> JSSemi- <|> keyword "if" *> liftA3 JSIf parensExpr stmt (maybeP (keyword "else" *> stmt))- <|> keyword "while" *> liftA2 JSWhile parensExpr stmt- <|> (keyword "for" *> parens- (try (liftA2 JSForIn varsOrExprs (keyword "in" *> expr))- <|> liftA3 JSFor (maybeP varsOrExprs <* semi) (optExpr <* semi) optExpr)- <*> stmt)- <|> keyword "break" $> JSBreak- <|> keyword "continue" $> JSContinue- <|> keyword "with" *> liftA2 JSWith parensExpr stmt- <|> keyword "return" *> (JSReturn <$> optExpr)- <|> JSBlock <$> compound- <|> JSNaked <$> varsOrExprs- varsOrExprs :: Parser s (Either [JSVar] JSExpr)- varsOrExprs = (keyword "var" *> commaSep1 variable) <+> expr- variable :: Parser s JSVar- variable = liftA2 JSVar identifier (maybeP (symbol '=' *> asgn))- parensExpr :: Parser s JSExpr- parensExpr = parens expr- optExpr :: Parser s (Maybe JSExpr)- optExpr = maybeP expr- expr :: Parser s JSExpr- expr = commaSep1 asgn- asgn :: Parser s JSExpr'- asgn = chainl1 condExpr (symbol '=' $> JSAsgn)- condExpr :: Parser s JSExpr'- condExpr = liftA2 jsCondExprBuild expr' (maybeP ((symbol '?' *> asgn) <~> (symbol ':' *> asgn)))- expr' :: Parser s JSExpr'- expr' = precedence- [ Prefix [ operator "--" $> jsDec, operator "++" $> jsInc- , operator "-" $> jsNeg, operator "+" $> jsPlus- , operator "~" $> jsBitNeg, operator "!" $> jsNot ]- , Postfix [ operator "--" $> jsDec, operator "++" $> jsInc ]- , InfixL [ operator "*" $> JSMul, operator "/" $> JSDiv- , operator "%" $> JSMod ]- , InfixL [ operator "+" $> JSAdd, operator "-" $> JSSub ]- , InfixL [ operator "<<" $> JSShl, operator ">>" $> JSShr ]- , InfixL [ operator "<=" $> JSLe, operator "<" $> JSLt- , operator ">=" $> JSGe, operator ">" $> JSGt ]- , InfixL [ operator "==" $> JSEq, operator "!=" $> JSNe ]- , InfixL [ try (operator "&") $> JSBitAnd ]- , InfixL [ operator "^" $> JSBitXor ]- , InfixL [ try (operator "|") $> JSBitOr ]- , InfixL [ operator "&&" $> JSAnd ]- , InfixL [ operator "||" $> JSOr ]- ]- (JSUnary <$> memOrCon)- memOrCon :: Parser s JSUnary- memOrCon = keyword "delete" *> (JSDel <$> member)- <|> keyword "new" *> (JSCons <$> con)- <|> JSMember <$> member- con :: Parser s JSCons- con = liftA2 JSQual (keyword "this" $> "this") (dot *> conCall) <|> conCall- conCall :: Parser s JSCons- conCall = identifier <**>- (dot *> (flip JSQual <$> conCall)- <|> flip JSConCall <$> parens (commaSep asgn)- <|> pure (\name -> JSConCall name []))- member :: Parser s JSMember- member = primaryExpr <**>- (flip JSCall <$> parens (commaSep asgn)- <|> flip JSIndex <$> brackets expr- <|> dot *> ((flip JSAccess) <$> member)- <|> pure JSPrimExp)- primaryExpr :: Parser s JSAtom- primaryExpr = JSParens <$> parens expr- <|> JSArray <$> brackets (commaSep asgn)- <|> JSId <$> identifier- <|> either JSInt JSFloat <$> naturalOrFloat- <|> JSString <$> stringLiteral- <|> JSTrue <$ keyword "true"- <|> JSFalse <$ keyword "false"- <|> JSNull <$ keyword "null"- <|> JSThis <$ keyword "this"-- -- Token Parsers- space :: Parser s ()- space = void (satisfy isSpace)- whitespace :: Parser s ()- whitespace = skipMany (spaces <|> oneLineComment <|> multiLineComment)- keyword :: String -> Parser s ()- keyword s = try (string s *> notIdentLetter) *> whitespace- operator :: String -> Parser s ()- operator op = try (string op *> notOpLetter) *> whitespace- identifier :: Parser s String- identifier = try ((identStart <:> many identLetter) >?> jsUnreservedName) <* whitespace- naturalOrFloat :: Parser s (Either Int Double)- naturalOrFloat = natFloat <* whitespace-- -- Nonsense to deal with floats and ints- natFloat :: Parser s (Either Int Double)- natFloat = char '0' *> zeroNumFloat <|> decimalFloat-- zeroNumFloat :: Parser s (Either Int Double)- zeroNumFloat = Left <$> (hexadecimal <|> octal)- <|> decimalFloat- <|> (fromMaybeP (fractFloat <*> pure 0) empty)- <|> pure (Left 0)-- decimalFloat :: Parser s (Either Int Double)- decimalFloat = fromMaybeP (decimal <**> (option (Just . Left) fractFloat)) empty-- fractFloat :: Parser s (Int -> Maybe (Either Int Double))- fractFloat = f <$> fractExponent- where- f g x = fmap Right (g x)-- fractExponent :: Parser s (Int -> Maybe Double)- fractExponent = f <$> fraction <*> option "" exponent'- <|> f <$> pure "" <*> exponent'- where- f fract exp n = readMaybe (show n ++ fract ++ exp)-- fraction :: Parser s [Char]- fraction = ('.' :) <$> (char '.'- *> some (oneOf ['0'..'9']))-- exponent' :: Parser s [Char]- exponent' = ('e' :) <$> (oneOf "eE"- *> ((((:) <$> oneOf "+-") <|> pure id)- <*> (show <$> decimal)))-- decimal :: Parser s Int- decimal = number 10 (oneOf ['0'..'9'])- hexadecimal = oneOf "xX" *> number 16 (oneOf (['a'..'f'] ++ ['A'..'F'] ++ ['0'..'9']))- octal = oneOf "oO" *> number 8 (oneOf ['0'..'7'])-- number :: Int -> Parser s Char -> Parser s Int- number base = pfoldl1 (\x d -> base * x + digitToInt d) 0-- stringLiteral :: Parser s String- stringLiteral = catMaybes <$> between (token "\"") (token "\"") (many stringChar) <* whitespace- symbol :: Char -> Parser s Char- symbol c = try (char c) <* whitespace- parens :: Parser s a -> Parser s a- parens = between (symbol '(') (symbol ')')- brackets :: Parser s a -> Parser s a- brackets = between (symbol '[') (symbol ']')- braces :: Parser s a -> Parser s a- braces = between (symbol '{') (symbol '}')- dot :: Parser s Char- dot = symbol '.'- semi :: Parser s Char- semi = symbol ';'- comma :: Parser s Char- comma = symbol ','- commaSep :: Parser s a -> Parser s [a]- commaSep p = sepBy p comma- commaSep1 :: Parser s a -> Parser s [a]- commaSep1 p = sepBy1 p comma-- -- Let bindings- spaces :: Parser s ()- spaces = skipSome space-- oneLineComment :: Parser s ()- oneLineComment = void (token "//" *> skipMany (satisfy (/= '\n')))-- multiLineComment :: Parser s ()- multiLineComment =- let inComment = void (token "*/")- <|> skipSome (noneOf "/*") *> inComment- <|> oneOf "/*" *> inComment- in token "/*" *> inComment-- identStart = satisfy jsIdentStart- identLetter = satisfy jsIdentLetter- notIdentLetter = notFollowedBy identLetter- notOpLetter = notFollowedBy (oneOf "+-*/=<>!~&|.%^")-- escChrs :: [Char]- escChrs = "abfntv\\\"'0123456789xo^ABCDEFGHLNRSUV"-- stringChar :: Parser s (Maybe Char)- stringChar = Just <$> satisfy jsStringLetter <|> stringEscape-- stringEscape :: Parser s (Maybe Char)- stringEscape = token "\\" *> (token "&" $> Nothing- <|> spaces *> token "\\" $> Nothing- <|> Just <$> escapeCode)-- escapeCode :: Parser s Char- escapeCode = match escChrs (oneOf escChrs) escCode empty- where- escCode 'a' = pure ('\a')- escCode 'b' = pure ('\b')- escCode 'f' = pure ('\f')- escCode 'n' = pure ('\n')- escCode 't' = pure ('\t')- escCode 'v' = pure ('\v')- escCode '\\' = pure ('\\')- escCode '"' = pure ('"')- escCode '\'' = pure ('\'')- escCode '^' = (\c -> toEnum (fromEnum c - fromEnum 'A' + 1)) <$> satisfy isUpper- escCode 'A' = token "CK" $> ('\ACK')- escCode 'B' = token "S" $> ('\BS') <|> token "EL" $> ('\BEL')- escCode 'C' = token "R" $> ('\CR') <|> token "AN" $> ('\CAN')- escCode 'D' = token "C" *> (token "1" $> ('\DC1')- <|> token "2" $> ('\DC2')- <|> token "3" $> ('\DC3')- <|> token "4" $> ('\DC4'))- <|> token "EL" $> ('\DEL')- <|> token "LE" $> ('\DLE')- escCode 'E' = token "M" $> ('\EM')- <|> token "T" *> (token "X" $> ('\ETX')- <|> token "B" $> ('\ETB'))- <|> token "SC" $> ('\ESC')- <|> token "OT" $> ('\EOT')- <|> token "NQ" $> ('\ENQ')- escCode 'F' = token "F" $> ('\FF') <|> token "S" $> ('\FS')- escCode 'G' = token "S" $> ('\GS')- escCode 'H' = token "T" $> ('\HT')- escCode 'L' = token "F" $> ('\LF')- escCode 'N' = token "UL" $> ('\NUL') <|> token "AK" $> ('\NAK')- escCode 'R' = token "S" $> ('\RS')- escCode 'S' = token "O" *> option (('\SO')) (token "H" $> ('\SOH'))- <|> token "I" $> ('\SI')- <|> token "P" $> ('\SP')- <|> token "TX" $> ('\STX')- <|> token "YN" $> ('\SYN')- <|> token "UB" $> ('\SUB')- escCode 'U' = token "S" $> ('\US')- escCode 'V' = token "T" $> ('\VT')- -- TODO numeric- escCode _ = empty--error "numeric escape codes not supported"
− benchmarks/JavascriptBench/Parsec/Parser.hs
@@ -1,244 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ScopedTypeVariables #-}-module JavascriptBench.Parsec.Parser where--import Shared.Parsec.Extended-import JavascriptBench.Shared--import Data.Char (isSpace, isUpper, digitToInt)-import Data.Maybe (catMaybes)-import Text.Read (readMaybe)--javascript :: forall s. Stream s Identity Char => Parser s JSProgram-javascript = whitespace *> many element <* eof- where- element :: Parser s JSElement- element = keyword "function" *> liftA3 JSFunction identifier (parens (commaSep identifier)) compound- <|> JSStm <$> stmt- compound :: Parser s JSCompoundStm- compound = braces (many stmt)- stmt :: Parser s JSStm- stmt = semi $> JSSemi- <|> keyword "if" *> liftA3 JSIf parensExpr stmt (maybeP (keyword "else" *> stmt))- <|> keyword "while" *> liftA2 JSWhile parensExpr stmt- <|> (keyword "for" *> parens- (try (liftA2 JSForIn varsOrExprs (keyword "in" *> expr))- <|> liftA3 JSFor (maybeP varsOrExprs <* semi) (optExpr <* semi) optExpr)- <*> stmt)- <|> keyword "break" $> JSBreak- <|> keyword "continue" $> JSContinue- <|> keyword "with" *> liftA2 JSWith parensExpr stmt- <|> keyword "return" *> (JSReturn <$> optExpr)- <|> JSBlock <$> compound- <|> JSNaked <$> varsOrExprs- varsOrExprs :: Parser s (Either [JSVar] JSExpr)- varsOrExprs = (keyword "var" *> commaSep1 variable) <+> expr- variable :: Parser s JSVar- variable = liftA2 JSVar identifier (maybeP (symbol '=' *> asgn))- parensExpr :: Parser s JSExpr- parensExpr = parens expr- optExpr :: Parser s (Maybe JSExpr)- optExpr = maybeP expr- expr :: Parser s JSExpr- expr = commaSep1 asgn- asgn :: Parser s JSExpr'- asgn = chainl1 condExpr (symbol '=' $> JSAsgn)- condExpr :: Parser s JSExpr'- condExpr = liftA2 jsCondExprBuild expr' (maybeP ((symbol '?' *> asgn) <~> (symbol ':' *> asgn)))- expr' :: Parser s JSExpr'- expr' = precedence- [ Prefix [ operator "--" $> jsDec, operator "++" $> jsInc- , operator "-" $> jsNeg, operator "+" $> jsPlus- , operator "~" $> jsBitNeg, operator "!" $> jsNot ]- , Postfix [ operator "--" $> jsDec, operator "++" $> jsInc ]- , InfixL [ operator "*" $> JSMul, operator "/" $> JSDiv- , operator "%" $> JSMod ]- , InfixL [ operator "+" $> JSAdd, operator "-" $> JSSub ]- , InfixL [ operator "<<" $> JSShl, operator ">>" $> JSShr ]- , InfixL [ operator "<=" $> JSLe, operator "<" $> JSLt- , operator ">=" $> JSGe, operator ">" $> JSGt ]- , InfixL [ operator "==" $> JSEq, operator "!=" $> JSNe ]- , InfixL [ try (operator "&") $> JSBitAnd ]- , InfixL [ operator "^" $> JSBitXor ]- , InfixL [ try (operator "|") $> JSBitOr ]- , InfixL [ operator "&&" $> JSAnd ]- , InfixL [ operator "||" $> JSOr ]- ]- (JSUnary <$> memOrCon)- memOrCon :: Parser s JSUnary- memOrCon = keyword "delete" *> (JSDel <$> member)- <|> keyword "new" *> (JSCons <$> con)- <|> JSMember <$> member- con :: Parser s JSCons- con = liftA2 JSQual (keyword "this" $> "this") (dot *> conCall) <|> conCall- conCall :: Parser s JSCons- conCall = identifier <**>- (dot *> (flip JSQual <$> conCall)- <|> flip JSConCall <$> parens (commaSep asgn)- <|> pure (\name -> JSConCall name []))- member :: Parser s JSMember- member = primaryExpr <**>- (flip JSCall <$> parens (commaSep asgn)- <|> flip JSIndex <$> brackets expr- <|> dot *> ((flip JSAccess) <$> member)- <|> pure JSPrimExp)- primaryExpr :: Parser s JSAtom- primaryExpr = JSParens <$> parens expr- <|> JSArray <$> brackets (commaSep asgn)- <|> JSId <$> identifier- <|> either JSInt JSFloat <$> naturalOrFloat- <|> JSString <$> stringLiteral- <|> JSTrue <$ keyword "true"- <|> JSFalse <$ keyword "false"- <|> JSNull <$ keyword "null"- <|> JSThis <$ keyword "this"-- -- Token Parsers- space :: Parser s ()- space = void (satisfy isSpace)- whitespace :: Parser s ()- whitespace = skipMany (spaces <|> oneLineComment <|> multiLineComment)- keyword :: String -> Parser s ()- keyword s = try (string s *> notIdentLetter) *> whitespace- operator :: String -> Parser s ()- operator op = try (string op *> notOpLetter) *> whitespace- identifier :: Parser s String- identifier = try ((identStart <:> many identLetter) >?> jsUnreservedName) <* whitespace- naturalOrFloat :: Parser s (Either Int Double)- naturalOrFloat = natFloat <* whitespace-- -- Nonsense to deal with floats and ints- natFloat :: Parser s (Either Int Double)- natFloat = char '0' *> zeroNumFloat <|> decimalFloat-- zeroNumFloat :: Parser s (Either Int Double)- zeroNumFloat = Left <$> (hexadecimal <|> octal)- <|> decimalFloat- <|> (fromMaybeP (fractFloat <*> pure 0) empty)- <|> pure (Left 0)-- decimalFloat :: Parser s (Either Int Double)- decimalFloat = fromMaybeP (decimal <**> (option (Just . Left) fractFloat)) empty-- fractFloat :: Parser s (Int -> Maybe (Either Int Double))- fractFloat = f <$> fractExponent- where- f g x = fmap Right (g x)-- fractExponent :: Parser s (Int -> Maybe Double)- fractExponent = f <$> fraction <*> option "" exponent'- <|> f <$> pure "" <*> exponent'- where- f fract exp n = readMaybe (show n ++ fract ++ exp)-- fraction :: Parser s [Char]- fraction = char '.' <:> some (oneOf ['0'..'9'])-- exponent' :: Parser s [Char]- exponent' = ('e' :) <$> (oneOf "eE"- *> ((((:) <$> oneOf "+-") <|> pure id)- <*> (show <$> decimal)))-- decimal :: Parser s Int- decimal = number 10 (oneOf ['0'..'9'])- hexadecimal = oneOf "xX" *> number 16 (oneOf (['a'..'f'] ++ ['A'..'F'] ++ ['0'..'9']))- octal = oneOf "oO" *> number 8 (oneOf ['0'..'7'])-- number :: Int -> Parser s Char -> Parser s Int- number base = pfoldl1 (\x d -> base * x + digitToInt d) 0-- stringLiteral :: Parser s String- stringLiteral = catMaybes <$> between (token "\"") (token "\"") (many stringChar) <* whitespace- symbol :: Char -> Parser s Char- symbol c = try (char c) <* whitespace- parens :: Parser s a -> Parser s a- parens = between (symbol '(') (symbol ')')- brackets :: Parser s a -> Parser s a- brackets = between (symbol '[') (symbol ']')- braces :: Parser s a -> Parser s a- braces = between (symbol '{') (symbol '}')- dot :: Parser s Char- dot = symbol '.'- semi :: Parser s Char- semi = symbol ';'- comma :: Parser s Char- comma = symbol ','- commaSep :: Parser s a -> Parser s [a]- commaSep p = sepBy p comma- commaSep1 :: Parser s a -> Parser s [a]- commaSep1 p = sepBy1 p comma-- -- Let bindings- spaces :: Parser s ()- spaces = skipSome space-- oneLineComment :: Parser s ()- oneLineComment = void (token "//" *> skipMany (satisfy (/= '\n')))-- multiLineComment :: Parser s ()- multiLineComment =- let inComment = void (token "*/")- <|> skipSome (satisfy (/= '*')) *> inComment- <|> char '*' *> inComment- in token "/*" *> inComment-- identStart = satisfy jsIdentStart- identLetter = satisfy jsIdentLetter- notIdentLetter = notFollowedBy identLetter- notOpLetter = notFollowedBy (oneOf "+-*/=<>!~&|.%^")-- escChrs :: [Char]- escChrs = "abfntv\\\"'0123456789xo^ABCDEFGHLNRSUV"-- stringChar :: Parser s (Maybe Char)- stringChar = Just <$> satisfy jsStringLetter <|> stringEscape-- stringEscape :: Parser s (Maybe Char)- stringEscape = token "\\" *> (token "&" $> Nothing- <|> spaces *> token "\\" $> Nothing- <|> Just <$> escapeCode)-- escapeCode :: Parser s Char- escapeCode = match escChrs (oneOf escChrs) escCode empty- where- escCode 'a' = pure ('\a')- escCode 'b' = pure ('\b')- escCode 'f' = pure ('\f')- escCode 'n' = pure ('\n')- escCode 't' = pure ('\t')- escCode 'v' = pure ('\v')- escCode '\\' = pure ('\\')- escCode '"' = pure ('"')- escCode '\'' = pure ('\'')- escCode '^' = (\c -> toEnum (fromEnum c - fromEnum 'A' + 1)) <$> satisfy isUpper- escCode 'A' = token "CK" $> ('\ACK')- escCode 'B' = token "S" $> ('\BS') <|> token "EL" $> ('\BEL')- escCode 'C' = token "R" $> ('\CR') <|> token "AN" $> ('\CAN')- escCode 'D' = token "C" *> (token "1" $> ('\DC1')- <|> token "2" $> ('\DC2')- <|> token "3" $> ('\DC3')- <|> token "4" $> ('\DC4'))- <|> token "EL" $> ('\DEL')- <|> token "LE" $> ('\DLE')- escCode 'E' = token "M" $> ('\EM')- <|> token "T" *> (token "X" $> ('\ETX')- <|> token "B" $> ('\ETB'))- <|> token "SC" $> ('\ESC')- <|> token "OT" $> ('\EOT')- <|> token "NQ" $> ('\ENQ')- escCode 'F' = token "F" $> ('\FF') <|> token "S" $> ('\FS')- escCode 'G' = token "S" $> ('\GS')- escCode 'H' = token "T" $> ('\HT')- escCode 'L' = token "F" $> ('\LF')- escCode 'N' = token "UL" $> ('\NUL') <|> token "AK" $> ('\NAK')- escCode 'R' = token "S" $> ('\RS')- escCode 'S' = token "O" *> option (('\SO')) (token "H" $> ('\SOH'))- <|> token "I" $> ('\SI')- <|> token "P" $> ('\SP')- <|> token "TX" $> ('\STX')- <|> token "YN" $> ('\SYN')- <|> token "UB" $> ('\SUB')- escCode 'U' = token "S" $> ('\US')- escCode 'V' = token "T" $> ('\VT')- -- TODO numeric- escCode _ = empty--error "numeric escape codes not supported"
− benchmarks/JavascriptBench/Parsley/Parser.hs
@@ -1,263 +0,0 @@-{-# OPTIONS_GHC -fplugin=Parsley.OverloadedQuotesPlugin #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE DeriveLift #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE PatternSynonyms #-}-module JavascriptBench.Parsley.Parser where--import Prelude hiding (fmap, pure, (<*), (*>), (<*>), (<$>), (<$), pred)-import Parsley-import Parsley.Char (token, oneOf, noneOf, digit)-import Parsley.Combinator (eof)-import Parsley.Fold (skipMany, skipSome, sepBy, sepBy1, somel, chainl1)-import Parsley.Precedence (precHomo, ops, Fixity(InfixL, Prefix, Postfix))-import Parsley.Defunctionalized (Defunc(CONS, ID, LIFTED, LAM_S), pattern FLIP_H, pattern COMPOSE_H)-import JavascriptBench.Shared-import Data.Char (isSpace, isUpper, digitToInt, isDigit)-import Data.Maybe (catMaybes)-import Text.Read (readMaybe)-import Control.Monad (liftM)-import Language.Haskell.TH.Syntax (Lift(..))--deriving instance Lift JSElement-deriving instance Lift JSStm-deriving instance Lift JSVar-deriving instance Lift JSExpr'-deriving instance Lift JSUnary-deriving instance Lift JSMember-deriving instance Lift JSCons-deriving instance Lift JSAtom--javascript :: Parser JSProgram-javascript = whitespace *> many element <* eof- where- element :: Parser JSElement- element = keyword "function" *> liftA3 [|JSFunction|] identifier (parens (commaSep identifier)) compound- <|> [|JSStm|] <$> stmt- compound :: Parser JSCompoundStm- compound = braces (many stmt)- stmt :: Parser JSStm- stmt = semi $> [|JSSemi|]- <|> keyword "if" *> liftA3 [|JSIf|] parensExpr stmt (maybeP (keyword "else" *> stmt))- <|> keyword "while" *> liftA2 [|JSWhile|] parensExpr stmt- <|> (keyword "for" *> parens- (try (liftA2 [|JSForIn|] varsOrExprs (keyword "in" *> expr))- <|> liftA3 [|JSFor|] (maybeP varsOrExprs <* semi) (optExpr <* semi) optExpr)- <*> stmt)- <|> keyword "break" $> [|JSBreak|]- <|> keyword "continue" $> [|JSContinue|]- <|> keyword "with" *> liftA2 [|JSWith|] parensExpr stmt- <|> keyword "return" *> ([|JSReturn|] <$> optExpr)- <|> [|JSBlock|] <$> compound- <|> [|JSNaked|] <$> varsOrExprs- varsOrExprs :: Parser (Either [JSVar] JSExpr)- varsOrExprs = keyword "var" *> commaSep1 variable <+> expr- variable :: Parser JSVar- variable = liftA2 [|JSVar|] identifier (maybeP (symbol '=' *> asgn))- parensExpr :: Parser JSExpr- parensExpr = parens expr- optExpr :: Parser (Maybe JSExpr)- optExpr = maybeP expr- expr :: Parser JSExpr- expr = commaSep1 asgn- asgn :: Parser JSExpr'- asgn = chainl1 condExpr (symbol '=' $> [|JSAsgn|])- condExpr :: Parser JSExpr'- condExpr = liftA2 [|jsCondExprBuild|] expr' (maybeP ((symbol '?' *> asgn) <~> (symbol ':' *> asgn)))- expr' :: Parser JSExpr'- expr' = precHomo ([|JSUnary|] <$> memOrCon)- [ ops Prefix [ operator "--" $> [|jsDec|], operator "++" $> [|jsInc|]- , operator "-" $> [|jsNeg|], operator "+" $> [|jsPlus|]- , operator "~" $> [|jsBitNeg|], operator "!" $> [|jsNot|] ]- , ops Postfix [ operator "--" $> [|jsDec|], operator "++" $> [|jsInc|] ]- , ops InfixL [ operator "*" $> [|JSMul|], operator "/" $> [|JSDiv|]- , operator "%" $> [|JSMod|] ]- , ops InfixL [ operator "+" $> [|JSAdd|], operator "-" $> [|JSSub|] ]- , ops InfixL [ operator "<<" $> [|JSShl|], operator ">>" $> [|JSShr|] ]- , ops InfixL [ operator "<=" $> [|JSLe|], operator "<" $> [|JSLt|]- , operator ">=" $> [|JSGe|], operator ">" $> [|JSGt|] ]- , ops InfixL [ operator "==" $> [|JSEq|], operator "!=" $> [|JSNe|] ]- , ops InfixL [ try (operator "&") $> [|JSBitAnd|] ]- , ops InfixL [ operator "^" $> [|JSBitXor|] ]- , ops InfixL [ try (operator "|") $> [|JSBitOr|] ]- , ops InfixL [ operator "&&" $> [|JSAnd|] ]- , ops InfixL [ operator "||" $> [|JSOr|] ]- ]- memOrCon :: Parser JSUnary- memOrCon = keyword "delete" *> ([|JSDel|] <$> member)- <|> keyword "new" *> ([|JSCons|] <$> con)- <|> [|JSMember|] <$> member- con :: Parser JSCons- con = liftA2 [|JSQual|] (keyword "this" $> [|"this"|]) (dot *> conCall) <|> conCall- conCall :: Parser JSCons- conCall = identifier <**>- (dot *> (FLIP_H [|JSQual|] <$> conCall)- <|> FLIP_H [|JSConCall|] <$> parens (commaSep asgn)- <|> pure (LAM_S $ \name -> [|JSConCall $name []|]))- member :: Parser JSMember- member = primaryExpr <**>- (FLIP_H [|JSCall|] <$> parens (commaSep asgn)- <|> FLIP_H [|JSIndex|] <$> brackets expr- <|> dot *> (FLIP_H [|JSAccess|] <$> member)- <|> pure [|JSPrimExp|])- primaryExpr :: Parser JSAtom- primaryExpr = [|JSParens|] <$> parens expr- <|> [|JSArray|] <$> brackets (commaSep asgn)- <|> [|JSId|] <$> identifier- <|> [|either JSInt JSFloat|] <$> naturalOrFloat- <|> [|JSString|] <$> stringLiteral- <|> [|JSTrue|] <$ keyword "true"- <|> [|JSFalse|] <$ keyword "false"- <|> [|JSNull|] <$ keyword "null"- <|> [|JSThis|] <$ keyword "this"-- -- Token Parsers- space :: Parser ()- space = void (satisfy [|isSpace|])- whitespace :: Parser ()- whitespace = skipMany (spaces <|> oneLineComment <|> multiLineComment)- keyword :: String -> Parser ()- keyword s = try (string s *> notIdentLetter) *> whitespace- operator :: String -> Parser ()- operator op = try (string op *> notOpLetter) *> whitespace- identifier :: Parser String- identifier = try ((identStart <:> many identLetter) >?> [|jsUnreservedName|]) <* whitespace- naturalOrFloat :: Parser (Either Int Double)- naturalOrFloat = natFloat <* whitespace-- -- Nonsense to deal with floats and ints- natFloat :: Parser (Either Int Double)- natFloat = char '0' *> zeroNumFloat <|> decimalFloat-- zeroNumFloat :: Parser (Either Int Double)- zeroNumFloat = [|Left|] <$> (hexadecimal <|> octal)- <|> decimalFloat- <|> fromMaybeP (fractFloat <*> pure (LIFTED 0)) empty- <|> pure [|Left 0|]-- decimalFloat :: Parser (Either Int Double)- decimalFloat = fromMaybeP (decimal <**> option (COMPOSE_H [|Just|] [|Left|]) fractFloat) empty-- fractFloat :: Parser (Int -> Maybe (Either Int Double))- fractFloat = [|\g x -> liftM Right (g x)|] <$> fractExponent-- fractExponent :: Parser (Int -> Maybe Double)- fractExponent = f <$> fraction <*> option [|""|] exponent'- <|> g <$> exponent'- where- f = [|\fract exp n -> readMaybe (show n ++ fract ++ exp)|]- g = [|\exp n -> readMaybe (show n ++ exp)|]-- fraction :: Parser [Char]- fraction = char '.' <:> some digit-- exponent' :: Parser [Char]- exponent' = [|$(CONS) 'e'|] <$> (oneOf "eE"- *> (((CONS <$> oneOf "+-") <|> pure ID)- <*> ([|show|] <$> decimal)))-- decimal :: Parser Int- decimal = number (LIFTED 10) digit- hexadecimal = oneOf "xX" *> number (LIFTED 16) (oneOf (['a'..'f'] ++ ['A'..'F'] ++ ['0'..'9']))- octal = oneOf "oO" *> number (LIFTED 8) (oneOf ['0'..'7'])-- number :: Defunc Int -> Parser Char -> Parser Int- number qbase digit = somel addDigit (LIFTED 0) digit- where- addDigit = [|\x d -> $qbase * x + digitToInt d|]-- stringLiteral :: Parser String- stringLiteral = [|catMaybes|] <$> between (token "\"") (token "\"") (many stringChar) <* whitespace- symbol :: Char -> Parser Char- symbol c = try (char c) <* whitespace- parens :: Parser a -> Parser a- parens = between (symbol '(') (symbol ')')- brackets :: Parser a -> Parser a- brackets = between (symbol '[') (symbol ']')- braces :: Parser a -> Parser a- braces = between (symbol '{') (symbol '}')- dot :: Parser Char- dot = symbol '.'- semi :: Parser Char- semi = symbol ';'- comma :: Parser Char- comma = symbol ','- commaSep :: Parser a -> Parser [a]- commaSep p = sepBy p comma- commaSep1 :: Parser a -> Parser [a]- commaSep1 p = sepBy1 p comma-- -- Let bindings- spaces :: Parser ()- spaces = skipSome space-- oneLineComment :: Parser ()- oneLineComment = void (token "//" *> skipMany (satisfy [|(/= '\n')|]))-- multiLineComment :: Parser ()- multiLineComment =- let inComment = void (token "*/")- <|> skipSome (noneOf "*") *> inComment- <|> char '*' *> inComment- in token "/*" *> inComment-- identStart = satisfy [|jsIdentStart|]- identLetter = satisfy [|jsIdentLetter|]- notIdentLetter = notFollowedBy identLetter- notOpLetter = notFollowedBy (oneOf "+-*/=<>!~&|.%^")-- escChrs :: [Char]- escChrs = "abfntv\\\"'0123456789xo^ABCDEFGHLNRSUV"-- stringChar :: Parser (Maybe Char)- stringChar = [|Just|] <$> satisfy [|jsStringLetter|] <|> stringEscape-- stringEscape :: Parser (Maybe Char)- stringEscape = token "\\" *> (token "&" $> [|Nothing|]- <|> spaces *> token "\\" $> [|Nothing|]- <|> [|Just|] <$> escapeCode)-- escapeCode :: Parser Char- escapeCode = match escChrs (oneOf escChrs) escCode empty- where- escCode 'a' = pure [|'\a'|]- escCode 'b' = pure [|'\b'|]- escCode 'f' = pure [|'\f'|]- escCode 'n' = pure [|'\n'|]- escCode 't' = pure [|'\t'|]- escCode 'v' = pure [|'\v'|]- escCode '\\' = pure [|'\\'|]- escCode '"' = pure [|'"'|]- escCode '\'' = pure [|'\''|]- escCode '^' = [|\c -> toEnum (fromEnum c - fromEnum 'A' + 1)|] <$> satisfy [|isUpper|]- escCode 'A' = token "CK" $> [|'\ACK'|]- escCode 'B' = token "S" $> [|'\BS'|] <|> token "EL" $> [|'\BEL'|]- escCode 'C' = token "R" $> [|'\CR'|] <|> token "AN" $> [|'\CAN'|]- escCode 'D' = token "C" *> (token "1" $> [|'\DC1'|]- <|> token "2" $> [|'\DC2'|]- <|> token "3" $> [|'\DC3'|]- <|> token "4" $> [|'\DC4'|])- <|> token "EL" $> [|'\DEL'|]- <|> token "LE" $> [|'\DLE'|]- escCode 'E' = token "M" $> [|'\EM'|]- <|> token "T" *> (token "X" $> [|'\ETX'|]- <|> token "B" $> [|'\ETB'|])- <|> token "SC" $> [|'\ESC'|]- <|> token "OT" $> [|'\EOT'|]- <|> token "NQ" $> [|'\ENQ'|]- escCode 'F' = token "F" $> [|'\FF'|] <|> token "S" $> [|'\FS'|]- escCode 'G' = token "S" $> [|'\GS'|]- escCode 'H' = token "T" $> [|'\HT'|]- escCode 'L' = token "F" $> [|'\LF'|]- escCode 'N' = token "UL" $> [|'\NUL'|] <|> token "AK" $> [|'\NAK'|]- escCode 'R' = token "S" $> [|'\RS'|]- escCode 'S' = token "O" *> option [|'\SO'|] (token "H" $> [|'\SOH'|])- <|> token "I" $> [|'\SI'|]- <|> token "P" $> [|'\SP'|]- <|> token "TX" $> [|'\STX'|]- <|> token "YN" $> [|'\SYN'|]- <|> token "UB" $> [|'\SUB'|]- escCode 'U' = token "S" $> [|'\US'|]- escCode 'V' = token "T" $> [|'\VT'|]- -- TODO numeric- escCode _ = empty--error "numeric escape codes not supported"
@@ -1,95 +0,0 @@-module JavascriptBench.Shared where--import Data.Char (isAlpha, isAlphaNum, isSpace, isUpper, isDigit, digitToInt)-import Data.Set (fromList, member)--type JSProgram = [JSElement]-type JSCompoundStm = [JSStm]-type JSExpr = [JSExpr']-data JSElement = JSFunction String [String] JSCompoundStm | JSStm JSStm deriving Show-data JSStm = JSSemi- | JSIf JSExpr JSStm (Maybe JSStm)- | JSWhile JSExpr JSStm- | JSFor (Maybe (Either [JSVar] JSExpr)) (Maybe JSExpr) (Maybe JSExpr) JSStm- | JSForIn (Either [JSVar] JSExpr) JSExpr JSStm- | JSBreak- | JSContinue- | JSWith JSExpr JSStm- | JSReturn (Maybe JSExpr)- | JSBlock JSCompoundStm- | JSNaked (Either [JSVar] JSExpr) deriving Show-data JSVar = JSVar String (Maybe JSExpr') deriving Show-data JSExpr' = JSAsgn JSExpr' JSExpr'- | JSCond JSExpr' JSExpr' JSExpr'- | JSOr JSExpr' JSExpr'- | JSAnd JSExpr' JSExpr'- | JSBitOr JSExpr' JSExpr'- | JSBitXor JSExpr' JSExpr'- | JSBitAnd JSExpr' JSExpr'- | JSEq JSExpr' JSExpr'- | JSNe JSExpr' JSExpr'- | JSLt JSExpr' JSExpr'- | JSGt JSExpr' JSExpr'- | JSLe JSExpr' JSExpr'- | JSGe JSExpr' JSExpr'- | JSShl JSExpr' JSExpr'- | JSShr JSExpr' JSExpr'- | JSAdd JSExpr' JSExpr'- | JSSub JSExpr' JSExpr'- | JSMul JSExpr' JSExpr'- | JSDiv JSExpr' JSExpr'- | JSMod JSExpr' JSExpr'- | JSUnary JSUnary deriving Show-data JSUnary = JSPlus JSUnary- | JSNeg JSUnary- | JSBitNeg JSUnary- | JSNot JSUnary- | JSInc JSUnary- | JSDec JSUnary- | JSNew JSCons- | JSDel JSMember- | JSMember JSMember- | JSCons JSCons deriving Show-jsPlus (JSUnary u) = JSUnary (JSPlus u)-jsNeg (JSUnary u) = JSUnary (JSNeg u)-jsBitNeg (JSUnary u) = JSUnary (JSBitNeg u)-jsNot (JSUnary u) = JSUnary (JSNot u)-jsInc (JSUnary u) = JSUnary (JSInc u)-jsDec (JSUnary u) = JSUnary (JSDec u)-data JSMember = JSPrimExp JSAtom- | JSAccess JSAtom JSMember- | JSIndex JSAtom JSExpr- | JSCall JSAtom JSExpr deriving Show-data JSCons = JSQual String JSCons- | JSConCall String JSExpr deriving Show-data JSAtom = JSParens JSExpr- | JSArray JSExpr- | JSId String- | JSInt Int- | JSFloat Double- | JSString String- | JSTrue- | JSFalse- | JSNull- | JSThis deriving Show--jsCondExprBuild :: JSExpr' -> Maybe (JSExpr', JSExpr') -> JSExpr'-jsCondExprBuild c (Just (t, e)) = JSCond c t e-jsCondExprBuild c Nothing = c--jsIdentStart :: Char -> Bool-jsIdentStart c = isAlpha c || c == '_'--jsIdentLetter :: Char -> Bool-jsIdentLetter c = isAlphaNum c || c == '_'--jsUnreservedName :: String -> Bool-jsUnreservedName = \s -> not (member s keys)- where- keys = fromList ["true", "false", "if", "else",- "for", "while", "break", "continue",- "function", "var", "new", "delete",- "this", "null", "return", "with"]--jsStringLetter :: Char -> Bool-jsStringLetter c = (c /= '"') && (c /= '\\') && (c > '\026')
− benchmarks/NandlangBench/Bison/Nandlang.tab.c
@@ -1,1601 +0,0 @@-/* A Bison parser, made by GNU Bison 3.5.1. */--/* Bison implementation for Yacc-like parsers in C-- Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,- Inc.-- This program is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- This program is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.-- You should have received a copy of the GNU General Public License- along with this program. If not, see <http://www.gnu.org/licenses/>. */--/* As a special exception, you may create a larger work that contains- part or all of the Bison parser skeleton and distribute that work- under terms of your choice, so long as that work isn't itself a- parser generator using the skeleton or a modified version thereof- as a parser skeleton. Alternatively, if you modify or redistribute- the parser skeleton itself, you may (at your option) remove this- special exception, which will cause the skeleton and the resulting- Bison output files to be licensed under the GNU General Public- License without this special exception.-- This special exception was added by the Free Software Foundation in- version 2.2 of Bison. */--/* C LALR(1) parser skeleton written by Richard Stallman, by- simplifying the original so-called "semantic" parser. */--/* All symbols defined below should begin with yy or YY, to avoid- infringing on user name space. This should be done even for local- variables, as they might otherwise be expanded by user macros.- There are some unavoidable exceptions within include files to- define necessary library symbols; they are noted "INFRINGES ON- USER NAME SPACE" below. */--/* Undocumented macros, especially those whose name start with YY_,- are private implementation details. Do not rely on them. */--/* Identify Bison output. */-#define YYBISON 1--/* Bison version. */-#define YYBISON_VERSION "3.5.1"--/* Skeleton name. */-#define YYSKELETON_NAME "yacc.c"--/* Pure parsers. */-#define YYPURE 0--/* Push parsers. */-#define YYPUSH 0--/* Pull parsers. */-#define YYPULL 1-----/* First part of user prologue. */-#line 1 "Nandlang.y"--#include <stdbool.h>-bool parse(const char*);-extern int yylex(void);-void yyerror(const char* err);--#line 77 "Nandlang.tab.c"--# ifndef YY_CAST-# ifdef __cplusplus-# define YY_CAST(Type, Val) static_cast<Type> (Val)-# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)-# else-# define YY_CAST(Type, Val) ((Type) (Val))-# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))-# endif-# endif-# ifndef YY_NULLPTR-# if defined __cplusplus-# if 201103L <= __cplusplus-# define YY_NULLPTR nullptr-# else-# define YY_NULLPTR 0-# endif-# else-# define YY_NULLPTR ((void*)0)-# endif-# endif--/* Enabling verbose error messages. */-#ifdef YYERROR_VERBOSE-# undef YYERROR_VERBOSE-# define YYERROR_VERBOSE 1-#else-# define YYERROR_VERBOSE 0-#endif--/* Use api.header.include to #include this header- instead of duplicating it here. */-#ifndef YY_YY_NANDLANG_TAB_H_INCLUDED-# define YY_YY_NANDLANG_TAB_H_INCLUDED-/* Debug traces. */-#ifndef YYDEBUG-# define YYDEBUG 0-#endif-#if YYDEBUG-extern int yydebug;-#endif--/* Token type. */-#ifndef YYTOKENTYPE-# define YYTOKENTYPE- enum yytokentype- {- IDENTIFIER = 258,- BIT = 259,- NAT = 260,- CHAR = 261,- FUNCTION = 262,- IF = 263,- WHILE = 264,- VAR = 265,- ELSE = 266- };-#endif--/* Value type. */-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED-typedef int YYSTYPE;-# define YYSTYPE_IS_TRIVIAL 1-# define YYSTYPE_IS_DECLARED 1-#endif---extern YYSTYPE yylval;--int yyparse (void);--#endif /* !YY_YY_NANDLANG_TAB_H_INCLUDED */----#ifdef short-# undef short-#endif--/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure- <limits.h> and (if available) <stdint.h> are included- so that the code can choose integer types of a good width. */--#ifndef __PTRDIFF_MAX__-# include <limits.h> /* INFRINGES ON USER NAME SPACE */-# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__-# include <stdint.h> /* INFRINGES ON USER NAME SPACE */-# define YY_STDINT_H-# endif-#endif--/* Narrow types that promote to a signed type and that can represent a- signed or unsigned integer of at least N bits. In tables they can- save space and decrease cache pressure. Promoting to a signed type- helps avoid bugs in integer arithmetic. */--#ifdef __INT_LEAST8_MAX__-typedef __INT_LEAST8_TYPE__ yytype_int8;-#elif defined YY_STDINT_H-typedef int_least8_t yytype_int8;-#else-typedef signed char yytype_int8;-#endif--#ifdef __INT_LEAST16_MAX__-typedef __INT_LEAST16_TYPE__ yytype_int16;-#elif defined YY_STDINT_H-typedef int_least16_t yytype_int16;-#else-typedef short yytype_int16;-#endif--#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__-typedef __UINT_LEAST8_TYPE__ yytype_uint8;-#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \- && UINT_LEAST8_MAX <= INT_MAX)-typedef uint_least8_t yytype_uint8;-#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX-typedef unsigned char yytype_uint8;-#else-typedef short yytype_uint8;-#endif--#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__-typedef __UINT_LEAST16_TYPE__ yytype_uint16;-#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \- && UINT_LEAST16_MAX <= INT_MAX)-typedef uint_least16_t yytype_uint16;-#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX-typedef unsigned short yytype_uint16;-#else-typedef int yytype_uint16;-#endif--#ifndef YYPTRDIFF_T-# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__-# define YYPTRDIFF_T __PTRDIFF_TYPE__-# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__-# elif defined PTRDIFF_MAX-# ifndef ptrdiff_t-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */-# endif-# define YYPTRDIFF_T ptrdiff_t-# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX-# else-# define YYPTRDIFF_T long-# define YYPTRDIFF_MAXIMUM LONG_MAX-# endif-#endif--#ifndef YYSIZE_T-# ifdef __SIZE_TYPE__-# define YYSIZE_T __SIZE_TYPE__-# elif defined size_t-# define YYSIZE_T size_t-# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */-# define YYSIZE_T size_t-# else-# define YYSIZE_T unsigned-# endif-#endif--#define YYSIZE_MAXIMUM \- YY_CAST (YYPTRDIFF_T, \- (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \- ? YYPTRDIFF_MAXIMUM \- : YY_CAST (YYSIZE_T, -1)))--#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))--/* Stored state numbers (used for stacks). */-typedef yytype_int8 yy_state_t;--/* State numbers in computations. */-typedef int yy_state_fast_t;--#ifndef YY_-# if defined YYENABLE_NLS && YYENABLE_NLS-# if ENABLE_NLS-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */-# define YY_(Msgid) dgettext ("bison-runtime", Msgid)-# endif-# endif-# ifndef YY_-# define YY_(Msgid) Msgid-# endif-#endif--#ifndef YY_ATTRIBUTE_PURE-# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)-# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))-# else-# define YY_ATTRIBUTE_PURE-# endif-#endif--#ifndef YY_ATTRIBUTE_UNUSED-# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)-# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))-# else-# define YY_ATTRIBUTE_UNUSED-# endif-#endif--/* Suppress unused-variable warnings by "using" E. */-#if ! defined lint || defined __GNUC__-# define YYUSE(E) ((void) (E))-#else-# define YYUSE(E) /* empty */-#endif--#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__-/* Suppress an incorrect diagnostic about yylval being uninitialized. */-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \- _Pragma ("GCC diagnostic push") \- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \- _Pragma ("GCC diagnostic pop")-#else-# define YY_INITIAL_VALUE(Value) Value-#endif-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN-# define YY_IGNORE_MAYBE_UNINITIALIZED_END-#endif-#ifndef YY_INITIAL_VALUE-# define YY_INITIAL_VALUE(Value) /* Nothing. */-#endif--#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__-# define YY_IGNORE_USELESS_CAST_BEGIN \- _Pragma ("GCC diagnostic push") \- _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")-# define YY_IGNORE_USELESS_CAST_END \- _Pragma ("GCC diagnostic pop")-#endif-#ifndef YY_IGNORE_USELESS_CAST_BEGIN-# define YY_IGNORE_USELESS_CAST_BEGIN-# define YY_IGNORE_USELESS_CAST_END-#endif---#define YY_ASSERT(E) ((void) (0 && (E)))--#if ! defined yyoverflow || YYERROR_VERBOSE--/* The parser invokes alloca or malloc; define the necessary symbols. */--# ifdef YYSTACK_USE_ALLOCA-# if YYSTACK_USE_ALLOCA-# ifdef __GNUC__-# define YYSTACK_ALLOC __builtin_alloca-# elif defined __BUILTIN_VA_ARG_INCR-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */-# elif defined _AIX-# define YYSTACK_ALLOC __alloca-# elif defined _MSC_VER-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */-# define alloca _alloca-# else-# define YYSTACK_ALLOC alloca-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */- /* Use EXIT_SUCCESS as a witness for stdlib.h. */-# ifndef EXIT_SUCCESS-# define EXIT_SUCCESS 0-# endif-# endif-# endif-# endif-# endif--# ifdef YYSTACK_ALLOC- /* Pacify GCC's 'empty if-body' warning. */-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)-# ifndef YYSTACK_ALLOC_MAXIMUM- /* The OS might guarantee only one guard page at the bottom of the stack,- and a page size can be as small as 4096 bytes. So we cannot safely- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number- to allow for a few compiler-allocated temporary stack slots. */-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */-# endif-# else-# define YYSTACK_ALLOC YYMALLOC-# define YYSTACK_FREE YYFREE-# ifndef YYSTACK_ALLOC_MAXIMUM-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM-# endif-# if (defined __cplusplus && ! defined EXIT_SUCCESS \- && ! ((defined YYMALLOC || defined malloc) \- && (defined YYFREE || defined free)))-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */-# ifndef EXIT_SUCCESS-# define EXIT_SUCCESS 0-# endif-# endif-# ifndef YYMALLOC-# define YYMALLOC malloc-# if ! defined malloc && ! defined EXIT_SUCCESS-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */-# endif-# endif-# ifndef YYFREE-# define YYFREE free-# if ! defined free && ! defined EXIT_SUCCESS-void free (void *); /* INFRINGES ON USER NAME SPACE */-# endif-# endif-# endif-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */---#if (! defined yyoverflow \- && (! defined __cplusplus \- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))--/* A type that is properly aligned for any stack member. */-union yyalloc-{- yy_state_t yyss_alloc;- YYSTYPE yyvs_alloc;-};--/* The size of the maximum gap between one aligned stack and the next. */-# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)--/* The size of an array large to enough to hold all stacks, each with- N elements. */-# define YYSTACK_BYTES(N) \- ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \- + YYSTACK_GAP_MAXIMUM)--# define YYCOPY_NEEDED 1--/* Relocate STACK from its old location to the new one. The- local variables YYSIZE and YYSTACKSIZE give the old and new number of- elements in the stack, and YYPTR gives the new location of the- stack. Advance YYPTR to a properly aligned location for the next- stack. */-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \- do \- { \- YYPTRDIFF_T yynewbytes; \- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \- Stack = &yyptr->Stack_alloc; \- yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \- yyptr += yynewbytes / YYSIZEOF (*yyptr); \- } \- while (0)--#endif--#if defined YYCOPY_NEEDED && YYCOPY_NEEDED-/* Copy COUNT objects from SRC to DST. The source and destination do- not overlap. */-# ifndef YYCOPY-# if defined __GNUC__ && 1 < __GNUC__-# define YYCOPY(Dst, Src, Count) \- __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))-# else-# define YYCOPY(Dst, Src, Count) \- do \- { \- YYPTRDIFF_T yyi; \- for (yyi = 0; yyi < (Count); yyi++) \- (Dst)[yyi] = (Src)[yyi]; \- } \- while (0)-# endif-# endif-#endif /* !YYCOPY_NEEDED */--/* YYFINAL -- State number of the termination state. */-#define YYFINAL 5-/* YYLAST -- Last index in YYTABLE. */-#define YYLAST 64--/* YYNTOKENS -- Number of terminals. */-#define YYNTOKENS 23-/* YYNNTS -- Number of nonterminals. */-#define YYNNTS 22-/* YYNRULES -- Number of rules. */-#define YYNRULES 41-/* YYNSTATES -- Number of states. */-#define YYNSTATES 71--#define YYUNDEFTOK 2-#define YYMAXUTOK 266---/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM- as returned by yylex, with out-of-bounds checking. */-#define YYTRANSLATE(YYX) \- (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)--/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM- as returned by yylex. */-static const yytype_int8 yytranslate[] =-{- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 14, 2, 2, 2, 2, 2, 2,- 15, 16, 2, 2, 17, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 18, 20,- 2, 19, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 12, 2, 13, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 21, 2, 22, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,- 5, 6, 7, 8, 9, 10, 11-};--#if YYDEBUG- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */-static const yytype_int8 yyrline[] =-{- 0, 22, 22, 22, 23, 24, 24, 25, 25, 26,- 26, 27, 27, 28, 28, 29, 30, 31, 32, 32,- 33, 34, 35, 35, 36, 37, 38, 39, 40, 41,- 42, 43, 43, 44, 45, 45, 45, 45, 46, 47,- 47, 48-};-#endif--#if YYDEBUG || YYERROR_VERBOSE || 0-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.- First, the terminals, then, starting at YYNTOKENS, nonterminals. */-static const char *const yytname[] =-{- "$end", "error", "$undefined", "IDENTIFIER", "BIT", "NAT", "CHAR",- "FUNCTION", "IF", "WHILE", "VAR", "ELSE", "'['", "']'", "'!'", "'('",- "')'", "','", "':'", "'='", "';'", "'{'", "'}'", "$accept", "nandlang",- "index", "natorbit", "variable", "literal", "expr", "nandexpr",- "funccallOrVar", "exprlist", "exprlist1", "varlist", "varlist1",- "funcparam", "varstmt", "ifstmt", "elsestmt", "whilestmt", "statement",- "block", "statements", "funcdef", YY_NULLPTR-};-#endif--# ifdef YYPRINT-/* YYTOKNUM[NUM] -- (External) token number corresponding to the- (internal) symbol number NUM (which must be that of a token). */-static const yytype_int16 yytoknum[] =-{- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,- 265, 266, 91, 93, 33, 40, 41, 44, 58, 61,- 59, 123, 125-};-# endif--#define YYPACT_NINF (-45)--#define yypact_value_is_default(Yyn) \- ((Yyn) == YYPACT_NINF)--#define YYTABLE_NINF (-18)--#define yytable_value_is_error(Yyn) \- 0-- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing- STATE-NUM. */-static const yytype_int8 yypact[] =-{- -3, 14, 19, -3, 16, -45, -45, 37, 34, 30,- 31, -45, 32, 39, -45, 37, 37, 29, -45, -45,- 38, -45, -45, 24, -45, -45, -5, -45, -45, 33,- 33, 37, -45, 4, -45, -45, 35, -45, -45, -45,- 24, 36, 33, 15, 26, -8, -8, 40, 33, -45,- 33, -45, -45, 28, 41, -45, -45, 42, -45, 33,- -45, 43, 33, -45, 29, -45, 44, -45, -45, -45,- -45-};-- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.- Performed when YYTABLE does not specify something else to do. Zero- means the default is an error. */-static const yytype_int8 yydefact[] =-{- 3, 0, 0, 3, 0, 1, 2, 23, 7, 25,- 27, 22, 0, 0, 8, 0, 23, 0, 6, 5,- 0, 24, 26, 40, 41, 4, 7, 9, 10, 0,- 0, 0, 13, 0, 12, 14, 0, 36, 34, 35,- 40, 0, 19, 8, 17, 0, 0, 0, 0, 37,- 0, 39, 38, 21, 0, 18, 16, 32, 33, 0,- 11, 0, 0, 15, 0, 30, 0, 29, 20, 31,- 28-};-- /* YYPGOTO[NTERM-NUM]. */-static const yytype_int8 yypgoto[] =-{- -45, 49, -23, -45, -45, -45, -18, 7, -45, -45,- -36, 45, -15, -45, -45, -45, -45, -45, -45, -44,- 20, -45-};-- /* YYDEFGOTO[NTERM-NUM]. */-static const yytype_int8 yydefgoto[] =-{- -1, 2, 14, 20, 9, 32, 53, 34, 35, 54,- 55, 10, 11, 12, 37, 38, 65, 39, 40, 24,- 41, 3-};-- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If- positive, shift that token. If negative, reduce the rule whose- number is the opposite. If YYTABLE_NINF, syntax error. */-static const yytype_int8 yytable[] =-{- 21, 57, 58, 43, 1, 33, 48, 13, 36, -17,- 42, 45, 46, 23, 61, -17, 47, 4, 48, 5,- 69, 56, 33, 66, 49, 36, 68, 26, 27, -16,- 28, 7, 29, 30, 31, -16, 44, 27, 13, 28,- 8, 42, 48, 18, 19, 62, 13, 15, 17, 16,- 23, 25, 6, 64, 50, 60, 0, 63, 52, 59,- 51, 22, 0, 67, 70-};--static const yytype_int8 yycheck[] =-{- 15, 45, 46, 26, 7, 23, 14, 12, 23, 14,- 15, 29, 30, 21, 50, 20, 31, 3, 14, 0,- 64, 44, 40, 59, 20, 40, 62, 3, 4, 14,- 6, 15, 8, 9, 10, 20, 3, 4, 12, 6,- 3, 15, 14, 4, 5, 17, 12, 17, 16, 18,- 21, 13, 3, 11, 19, 48, -1, 16, 22, 19,- 40, 16, -1, 20, 20-};-- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing- symbol of state STATE-NUM. */-static const yytype_int8 yystos[] =-{- 0, 7, 24, 44, 3, 0, 24, 15, 3, 27,- 34, 35, 36, 12, 25, 17, 18, 16, 4, 5,- 26, 35, 34, 21, 42, 13, 3, 4, 6, 8,- 9, 10, 28, 29, 30, 31, 35, 37, 38, 40,- 41, 43, 15, 25, 3, 29, 29, 35, 14, 20,- 19, 43, 22, 29, 32, 33, 25, 42, 42, 19,- 30, 33, 17, 16, 11, 39, 33, 20, 33, 42,- 20-};-- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */-static const yytype_int8 yyr1[] =-{- 0, 23, 24, 24, 25, 26, 26, 27, 27, 28,- 28, 29, 29, 30, 30, 31, 31, 31, 32, 32,- 33, 33, 34, 34, 35, 35, 36, 36, 37, 37,- 38, 39, 39, 40, 41, 41, 41, 41, 42, 43,- 43, 44-};-- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */-static const yytype_int8 yyr2[] =-{- 0, 2, 2, 0, 3, 1, 1, 1, 2, 1,- 1, 3, 1, 1, 1, 4, 2, 1, 1, 0,- 3, 1, 1, 0, 3, 1, 3, 1, 5, 4,- 4, 2, 0, 3, 1, 1, 1, 2, 3, 2,- 0, 6-};---#define yyerrok (yyerrstatus = 0)-#define yyclearin (yychar = YYEMPTY)-#define YYEMPTY (-2)-#define YYEOF 0--#define YYACCEPT goto yyacceptlab-#define YYABORT goto yyabortlab-#define YYERROR goto yyerrorlab---#define YYRECOVERING() (!!yyerrstatus)--#define YYBACKUP(Token, Value) \- do \- if (yychar == YYEMPTY) \- { \- yychar = (Token); \- yylval = (Value); \- YYPOPSTACK (yylen); \- yystate = *yyssp; \- goto yybackup; \- } \- else \- { \- yyerror (YY_("syntax error: cannot back up")); \- YYERROR; \- } \- while (0)--/* Error token number */-#define YYTERROR 1-#define YYERRCODE 256----/* Enable debugging if requested. */-#if YYDEBUG--# ifndef YYFPRINTF-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */-# define YYFPRINTF fprintf-# endif--# define YYDPRINTF(Args) \-do { \- if (yydebug) \- YYFPRINTF Args; \-} while (0)--/* This macro is provided for backward compatibility. */-#ifndef YY_LOCATION_PRINT-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)-#endif---# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \-do { \- if (yydebug) \- { \- YYFPRINTF (stderr, "%s ", Title); \- yy_symbol_print (stderr, \- Type, Value); \- YYFPRINTF (stderr, "\n"); \- } \-} while (0)---/*-----------------------------------.-| Print this symbol's value on YYO. |-`-----------------------------------*/--static void-yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)-{- FILE *yyoutput = yyo;- YYUSE (yyoutput);- if (!yyvaluep)- return;-# ifdef YYPRINT- if (yytype < YYNTOKENS)- YYPRINT (yyo, yytoknum[yytype], *yyvaluep);-# endif- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN- YYUSE (yytype);- YY_IGNORE_MAYBE_UNINITIALIZED_END-}---/*---------------------------.-| Print this symbol on YYO. |-`---------------------------*/--static void-yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)-{- YYFPRINTF (yyo, "%s %s (",- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);-- yy_symbol_value_print (yyo, yytype, yyvaluep);- YYFPRINTF (yyo, ")");-}--/*------------------------------------------------------------------.-| yy_stack_print -- Print the state stack from its BOTTOM up to its |-| TOP (included). |-`------------------------------------------------------------------*/--static void-yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)-{- YYFPRINTF (stderr, "Stack now");- for (; yybottom <= yytop; yybottom++)- {- int yybot = *yybottom;- YYFPRINTF (stderr, " %d", yybot);- }- YYFPRINTF (stderr, "\n");-}--# define YY_STACK_PRINT(Bottom, Top) \-do { \- if (yydebug) \- yy_stack_print ((Bottom), (Top)); \-} while (0)---/*------------------------------------------------.-| Report that the YYRULE is going to be reduced. |-`------------------------------------------------*/--static void-yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule)-{- int yylno = yyrline[yyrule];- int yynrhs = yyr2[yyrule];- int yyi;- YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",- yyrule - 1, yylno);- /* The symbols being reduced. */- for (yyi = 0; yyi < yynrhs; yyi++)- {- YYFPRINTF (stderr, " $%d = ", yyi + 1);- yy_symbol_print (stderr,- yystos[+yyssp[yyi + 1 - yynrhs]],- &yyvsp[(yyi + 1) - (yynrhs)]- );- YYFPRINTF (stderr, "\n");- }-}--# define YY_REDUCE_PRINT(Rule) \-do { \- if (yydebug) \- yy_reduce_print (yyssp, yyvsp, Rule); \-} while (0)--/* Nonzero means print parse trace. It is left uninitialized so that- multiple parsers can coexist. */-int yydebug;-#else /* !YYDEBUG */-# define YYDPRINTF(Args)-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)-# define YY_STACK_PRINT(Bottom, Top)-# define YY_REDUCE_PRINT(Rule)-#endif /* !YYDEBUG */---/* YYINITDEPTH -- initial size of the parser's stacks. */-#ifndef YYINITDEPTH-# define YYINITDEPTH 200-#endif--/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only- if the built-in stack extension method is used).-- Do not make this value too large; the results are undefined if- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)- evaluated with infinite-precision integer arithmetic. */--#ifndef YYMAXDEPTH-# define YYMAXDEPTH 10000-#endif---#if YYERROR_VERBOSE--# ifndef yystrlen-# if defined __GLIBC__ && defined _STRING_H-# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))-# else-/* Return the length of YYSTR. */-static YYPTRDIFF_T-yystrlen (const char *yystr)-{- YYPTRDIFF_T yylen;- for (yylen = 0; yystr[yylen]; yylen++)- continue;- return yylen;-}-# endif-# endif--# ifndef yystpcpy-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE-# define yystpcpy stpcpy-# else-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in- YYDEST. */-static char *-yystpcpy (char *yydest, const char *yysrc)-{- char *yyd = yydest;- const char *yys = yysrc;-- while ((*yyd++ = *yys++) != '\0')- continue;-- return yyd - 1;-}-# endif-# endif--# ifndef yytnamerr-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary- quotes and backslashes, so that it's suitable for yyerror. The- heuristic is that double-quoting is unnecessary unless the string- contains an apostrophe, a comma, or backslash (other than- backslash-backslash). YYSTR is taken from yytname. If YYRES is- null, do not copy; instead, return the length of what the result- would have been. */-static YYPTRDIFF_T-yytnamerr (char *yyres, const char *yystr)-{- if (*yystr == '"')- {- YYPTRDIFF_T yyn = 0;- char const *yyp = yystr;-- for (;;)- switch (*++yyp)- {- case '\'':- case ',':- goto do_not_strip_quotes;-- case '\\':- if (*++yyp != '\\')- goto do_not_strip_quotes;- else- goto append;-- append:- default:- if (yyres)- yyres[yyn] = *yyp;- yyn++;- break;-- case '"':- if (yyres)- yyres[yyn] = '\0';- return yyn;- }- do_not_strip_quotes: ;- }-- if (yyres)- return yystpcpy (yyres, yystr) - yyres;- else- return yystrlen (yystr);-}-# endif--/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message- about the unexpected token YYTOKEN for the state stack whose top is- YYSSP.-- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is- not large enough to hold the message. In that case, also set- *YYMSG_ALLOC to the required number of bytes. Return 2 if the- required number of bytes is too large to store. */-static int-yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,- yy_state_t *yyssp, int yytoken)-{- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };- /* Internationalized format string. */- const char *yyformat = YY_NULLPTR;- /* Arguments of yyformat: reported tokens (one for the "unexpected",- one per "expected"). */- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];- /* Actual size of YYARG. */- int yycount = 0;- /* Cumulated lengths of YYARG. */- YYPTRDIFF_T yysize = 0;-- /* There are many possibilities here to consider:- - If this state is a consistent state with a default action, then- the only way this function was invoked is if the default action- is an error action. In that case, don't check for expected- tokens because there are none.- - The only way there can be no lookahead present (in yychar) is if- this state is a consistent state with a default action. Thus,- detecting the absence of a lookahead is sufficient to determine- that there is no unexpected or expected token to report. In that- case, just report a simple "syntax error".- - Don't assume there isn't a lookahead just because this state is a- consistent state with a default action. There might have been a- previous inconsistent state, consistent state with a non-default- action, or user semantic action that manipulated yychar.- - Of course, the expected token list depends on states to have- correct lookahead information, and it depends on the parser not- to perform extra reductions after fetching a lookahead from the- scanner and before detecting a syntax error. Thus, state merging- (from LALR or IELR) and default reductions corrupt the expected- token list. However, the list is correct for canonical LR with- one exception: it will still contain any token that will not be- accepted due to an error action in a later state.- */- if (yytoken != YYEMPTY)- {- int yyn = yypact[+*yyssp];- YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);- yysize = yysize0;- yyarg[yycount++] = yytname[yytoken];- if (!yypact_value_is_default (yyn))- {- /* Start YYX at -YYN if negative to avoid negative indexes in- YYCHECK. In other words, skip the first -YYN actions for- this state because they are default actions. */- int yyxbegin = yyn < 0 ? -yyn : 0;- /* Stay within bounds of both yycheck and yytname. */- int yychecklim = YYLAST - yyn + 1;- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;- int yyx;-- for (yyx = yyxbegin; yyx < yyxend; ++yyx)- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR- && !yytable_value_is_error (yytable[yyx + yyn]))- {- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)- {- yycount = 1;- yysize = yysize0;- break;- }- yyarg[yycount++] = yytname[yyx];- {- YYPTRDIFF_T yysize1- = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);- if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)- yysize = yysize1;- else- return 2;- }- }- }- }-- switch (yycount)- {-# define YYCASE_(N, S) \- case N: \- yyformat = S; \- break- default: /* Avoid compiler warnings. */- YYCASE_(0, YY_("syntax error"));- YYCASE_(1, YY_("syntax error, unexpected %s"));- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));-# undef YYCASE_- }-- {- /* Don't count the "%s"s in the final size, but reserve room for- the terminator. */- YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1;- if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)- yysize = yysize1;- else- return 2;- }-- if (*yymsg_alloc < yysize)- {- *yymsg_alloc = 2 * yysize;- if (! (yysize <= *yymsg_alloc- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;- return 1;- }-- /* Avoid sprintf, as that infringes on the user's name space.- Don't have undefined behavior even if the translation- produced a string with the wrong number of "%s"s. */- {- char *yyp = *yymsg;- int yyi = 0;- while ((*yyp = *yyformat) != '\0')- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)- {- yyp += yytnamerr (yyp, yyarg[yyi++]);- yyformat += 2;- }- else- {- ++yyp;- ++yyformat;- }- }- return 0;-}-#endif /* YYERROR_VERBOSE */--/*-----------------------------------------------.-| Release the memory associated to this symbol. |-`-----------------------------------------------*/--static void-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)-{- YYUSE (yyvaluep);- if (!yymsg)- yymsg = "Deleting";- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);-- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN- YYUSE (yytype);- YY_IGNORE_MAYBE_UNINITIALIZED_END-}-----/* The lookahead symbol. */-int yychar;--/* The semantic value of the lookahead symbol. */-YYSTYPE yylval;-/* Number of syntax errors so far. */-int yynerrs;---/*----------.-| yyparse. |-`----------*/--int-yyparse (void)-{- yy_state_fast_t yystate;- /* Number of tokens to shift before error messages enabled. */- int yyerrstatus;-- /* The stacks and their tools:- 'yyss': related to states.- 'yyvs': related to semantic values.-- Refer to the stacks through separate pointers, to allow yyoverflow- to reallocate them elsewhere. */-- /* The state stack. */- yy_state_t yyssa[YYINITDEPTH];- yy_state_t *yyss;- yy_state_t *yyssp;-- /* The semantic value stack. */- YYSTYPE yyvsa[YYINITDEPTH];- YYSTYPE *yyvs;- YYSTYPE *yyvsp;-- YYPTRDIFF_T yystacksize;-- int yyn;- int yyresult;- /* Lookahead token as an internal (translated) token number. */- int yytoken = 0;- /* The variables used to return semantic value and location from the- action routines. */- YYSTYPE yyval;--#if YYERROR_VERBOSE- /* Buffer for error messages, and its allocated size. */- char yymsgbuf[128];- char *yymsg = yymsgbuf;- YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf;-#endif--#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))-- /* The number of symbols on the RHS of the reduced rule.- Keep to zero when no symbol should be popped. */- int yylen = 0;-- yyssp = yyss = yyssa;- yyvsp = yyvs = yyvsa;- yystacksize = YYINITDEPTH;-- YYDPRINTF ((stderr, "Starting parse\n"));-- yystate = 0;- yyerrstatus = 0;- yynerrs = 0;- yychar = YYEMPTY; /* Cause a token to be read. */- goto yysetstate;---/*------------------------------------------------------------.-| yynewstate -- push a new state, which is found in yystate. |-`------------------------------------------------------------*/-yynewstate:- /* In all cases, when you get here, the value and location stacks- have just been pushed. So pushing a state here evens the stacks. */- yyssp++;---/*--------------------------------------------------------------------.-| yysetstate -- set current state (the top of the stack) to yystate. |-`--------------------------------------------------------------------*/-yysetstate:- YYDPRINTF ((stderr, "Entering state %d\n", yystate));- YY_ASSERT (0 <= yystate && yystate < YYNSTATES);- YY_IGNORE_USELESS_CAST_BEGIN- *yyssp = YY_CAST (yy_state_t, yystate);- YY_IGNORE_USELESS_CAST_END-- if (yyss + yystacksize - 1 <= yyssp)-#if !defined yyoverflow && !defined YYSTACK_RELOCATE- goto yyexhaustedlab;-#else- {- /* Get the current used size of the three stacks, in elements. */- YYPTRDIFF_T yysize = yyssp - yyss + 1;--# if defined yyoverflow- {- /* Give user a chance to reallocate the stack. Use copies of- these so that the &'s don't force the real ones into- memory. */- yy_state_t *yyss1 = yyss;- YYSTYPE *yyvs1 = yyvs;-- /* Each stack pointer address is followed by the size of the- data in use in that stack, in bytes. This used to be a- conditional around just the two extra args, but that might- be undefined if yyoverflow is a macro. */- yyoverflow (YY_("memory exhausted"),- &yyss1, yysize * YYSIZEOF (*yyssp),- &yyvs1, yysize * YYSIZEOF (*yyvsp),- &yystacksize);- yyss = yyss1;- yyvs = yyvs1;- }-# else /* defined YYSTACK_RELOCATE */- /* Extend the stack our own way. */- if (YYMAXDEPTH <= yystacksize)- goto yyexhaustedlab;- yystacksize *= 2;- if (YYMAXDEPTH < yystacksize)- yystacksize = YYMAXDEPTH;-- {- yy_state_t *yyss1 = yyss;- union yyalloc *yyptr =- YY_CAST (union yyalloc *,- YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));- if (! yyptr)- goto yyexhaustedlab;- YYSTACK_RELOCATE (yyss_alloc, yyss);- YYSTACK_RELOCATE (yyvs_alloc, yyvs);-# undef YYSTACK_RELOCATE- if (yyss1 != yyssa)- YYSTACK_FREE (yyss1);- }-# endif-- yyssp = yyss + yysize - 1;- yyvsp = yyvs + yysize - 1;-- YY_IGNORE_USELESS_CAST_BEGIN- YYDPRINTF ((stderr, "Stack size increased to %ld\n",- YY_CAST (long, yystacksize)));- YY_IGNORE_USELESS_CAST_END-- if (yyss + yystacksize - 1 <= yyssp)- YYABORT;- }-#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */-- if (yystate == YYFINAL)- YYACCEPT;-- goto yybackup;---/*-----------.-| yybackup. |-`-----------*/-yybackup:- /* Do appropriate processing given the current state. Read a- lookahead token if we need one and don't already have one. */-- /* First try to decide what to do without reference to lookahead token. */- yyn = yypact[yystate];- if (yypact_value_is_default (yyn))- goto yydefault;-- /* Not known => get a lookahead token if don't already have one. */-- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */- if (yychar == YYEMPTY)- {- YYDPRINTF ((stderr, "Reading a token: "));- yychar = yylex ();- }-- if (yychar <= YYEOF)- {- yychar = yytoken = YYEOF;- YYDPRINTF ((stderr, "Now at end of input.\n"));- }- else- {- yytoken = YYTRANSLATE (yychar);- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);- }-- /* If the proper action on seeing token YYTOKEN is to reduce or to- detect an error, take that action. */- yyn += yytoken;- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)- goto yydefault;- yyn = yytable[yyn];- if (yyn <= 0)- {- if (yytable_value_is_error (yyn))- goto yyerrlab;- yyn = -yyn;- goto yyreduce;- }-- /* Count tokens shifted since error; after three, turn off error- status. */- if (yyerrstatus)- yyerrstatus--;-- /* Shift the lookahead token. */- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);- yystate = yyn;- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN- *++yyvsp = yylval;- YY_IGNORE_MAYBE_UNINITIALIZED_END-- /* Discard the shifted token. */- yychar = YYEMPTY;- goto yynewstate;---/*-----------------------------------------------------------.-| yydefault -- do the default action for the current state. |-`-----------------------------------------------------------*/-yydefault:- yyn = yydefact[yystate];- if (yyn == 0)- goto yyerrlab;- goto yyreduce;---/*-----------------------------.-| yyreduce -- do a reduction. |-`-----------------------------*/-yyreduce:- /* yyn is the number of a rule to reduce with. */- yylen = yyr2[yyn];-- /* If YYLEN is nonzero, implement the default value of the action:- '$$ = $1'.-- Otherwise, the following line sets YYVAL to garbage.- This behavior is undocumented and Bison- users should not rely upon it. Assigning to YYVAL- unconditionally makes the parser a bit smaller, and it avoids a- GCC warning that YYVAL may be used uninitialized. */- yyval = yyvsp[1-yylen];--- YY_REDUCE_PRINT (yyn);- switch (yyn)- {--#line 1353 "Nandlang.tab.c"-- default: break;- }- /* User semantic actions sometimes alter yychar, and that requires- that yytoken be updated with the new translation. We take the- approach of translating immediately before every use of yytoken.- One alternative is translating here after every semantic action,- but that translation would be missed if the semantic action invokes- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an- incorrect destructor might then be invoked immediately. In the- case of YYERROR or YYBACKUP, subsequent parser actions might lead- to an incorrect destructor call or verbose syntax error message- before the lookahead is translated. */- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);-- YYPOPSTACK (yylen);- yylen = 0;- YY_STACK_PRINT (yyss, yyssp);-- *++yyvsp = yyval;-- /* Now 'shift' the result of the reduction. Determine what state- that goes to, based on the state we popped back to and the rule- number reduced by. */- {- const int yylhs = yyr1[yyn] - YYNTOKENS;- const int yyi = yypgoto[yylhs] + *yyssp;- yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp- ? yytable[yyi]- : yydefgoto[yylhs]);- }-- goto yynewstate;---/*--------------------------------------.-| yyerrlab -- here on detecting error. |-`--------------------------------------*/-yyerrlab:- /* Make sure we have latest lookahead translation. See comments at- user semantic actions for why this is necessary. */- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);-- /* If not already recovering from an error, report this error. */- if (!yyerrstatus)- {- ++yynerrs;-#if ! YYERROR_VERBOSE- yyerror (YY_("syntax error"));-#else-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \- yyssp, yytoken)- {- char const *yymsgp = YY_("syntax error");- int yysyntax_error_status;- yysyntax_error_status = YYSYNTAX_ERROR;- if (yysyntax_error_status == 0)- yymsgp = yymsg;- else if (yysyntax_error_status == 1)- {- if (yymsg != yymsgbuf)- YYSTACK_FREE (yymsg);- yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc)));- if (!yymsg)- {- yymsg = yymsgbuf;- yymsg_alloc = sizeof yymsgbuf;- yysyntax_error_status = 2;- }- else- {- yysyntax_error_status = YYSYNTAX_ERROR;- yymsgp = yymsg;- }- }- yyerror (yymsgp);- if (yysyntax_error_status == 2)- goto yyexhaustedlab;- }-# undef YYSYNTAX_ERROR-#endif- }---- if (yyerrstatus == 3)- {- /* If just tried and failed to reuse lookahead token after an- error, discard it. */-- if (yychar <= YYEOF)- {- /* Return failure if at end of input. */- if (yychar == YYEOF)- YYABORT;- }- else- {- yydestruct ("Error: discarding",- yytoken, &yylval);- yychar = YYEMPTY;- }- }-- /* Else will try to reuse lookahead token after shifting the error- token. */- goto yyerrlab1;---/*---------------------------------------------------.-| yyerrorlab -- error raised explicitly by YYERROR. |-`---------------------------------------------------*/-yyerrorlab:- /* Pacify compilers when the user code never invokes YYERROR and the- label yyerrorlab therefore never appears in user code. */- if (0)- YYERROR;-- /* Do not reclaim the symbols of the rule whose action triggered- this YYERROR. */- YYPOPSTACK (yylen);- yylen = 0;- YY_STACK_PRINT (yyss, yyssp);- yystate = *yyssp;- goto yyerrlab1;---/*-------------------------------------------------------------.-| yyerrlab1 -- common code for both syntax error and YYERROR. |-`-------------------------------------------------------------*/-yyerrlab1:- yyerrstatus = 3; /* Each real token shifted decrements this. */-- for (;;)- {- yyn = yypact[yystate];- if (!yypact_value_is_default (yyn))- {- yyn += YYTERROR;- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)- {- yyn = yytable[yyn];- if (0 < yyn)- break;- }- }-- /* Pop the current state because it cannot handle the error token. */- if (yyssp == yyss)- YYABORT;--- yydestruct ("Error: popping",- yystos[yystate], yyvsp);- YYPOPSTACK (1);- yystate = *yyssp;- YY_STACK_PRINT (yyss, yyssp);- }-- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN- *++yyvsp = yylval;- YY_IGNORE_MAYBE_UNINITIALIZED_END--- /* Shift the error token. */- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);-- yystate = yyn;- goto yynewstate;---/*-------------------------------------.-| yyacceptlab -- YYACCEPT comes here. |-`-------------------------------------*/-yyacceptlab:- yyresult = 0;- goto yyreturn;---/*-----------------------------------.-| yyabortlab -- YYABORT comes here. |-`-----------------------------------*/-yyabortlab:- yyresult = 1;- goto yyreturn;---#if !defined yyoverflow || YYERROR_VERBOSE-/*-------------------------------------------------.-| yyexhaustedlab -- memory exhaustion comes here. |-`-------------------------------------------------*/-yyexhaustedlab:- yyerror (YY_("memory exhausted"));- yyresult = 2;- /* Fall through. */-#endif---/*-----------------------------------------------------.-| yyreturn -- parsing is finished, return the result. |-`-----------------------------------------------------*/-yyreturn:- if (yychar != YYEMPTY)- {- /* Make sure we have latest lookahead translation. See comments at- user semantic actions for why this is necessary. */- yytoken = YYTRANSLATE (yychar);- yydestruct ("Cleanup: discarding lookahead",- yytoken, &yylval);- }- /* Do not reclaim the symbols of the rule whose action triggered- this YYABORT or YYACCEPT. */- YYPOPSTACK (yylen);- YY_STACK_PRINT (yyss, yyssp);- while (yyssp != yyss)- {- yydestruct ("Cleanup: popping",- yystos[+*yyssp], yyvsp);- YYPOPSTACK (1);- }-#ifndef yyoverflow- if (yyss != yyssa)- YYSTACK_FREE (yyss);-#endif-#if YYERROR_VERBOSE- if (yymsg != yymsgbuf)- YYSTACK_FREE (yymsg);-#endif- return yyresult;-}-#line 50 "Nandlang.y"---void set_input_string(const char* in);-void end_lexical_scan(void);--bool parse(const char* in)-{- set_input_string(in);- int rv = yyparse();- end_lexical_scan();- return !rv;-}--void yyerror(const char* msg)-{- return;-}
− benchmarks/NandlangBench/Bison/Parser.hs
@@ -1,15 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface #-}-module NandlangBench.Bison.Parser where--import Foreign.C-import Foreign.Ptr-import Data.ByteString-import System.IO.Unsafe--foreign import ccall "parse" c_parse :: Ptr CChar -> CBool--marshall :: ByteString -> CBool-marshall = unsafePerformIO . flip useAsCString (return . c_parse)--nand :: ByteString -> Maybe ()-nand str = if marshall str == 1 then Just () else Nothing
− benchmarks/NandlangBench/Bison/lex.yy.c
@@ -1,1948 +0,0 @@--#line 3 "lex.yy.c"--#define YY_INT_ALIGNED short int--/* A lexical scanner generated by flex */--#define FLEX_SCANNER-#define YY_FLEX_MAJOR_VERSION 2-#define YY_FLEX_MINOR_VERSION 6-#define YY_FLEX_SUBMINOR_VERSION 4-#if YY_FLEX_SUBMINOR_VERSION > 0-#define FLEX_BETA-#endif--/* First, we deal with platform-specific or compiler-specific issues. */--/* begin standard C headers. */-#include <stdio.h>-#include <string.h>-#include <errno.h>-#include <stdlib.h>--/* end standard C headers. */--/* flex integer type definitions */--#ifndef FLEXINT_H-#define FLEXINT_H--/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */--#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L--/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,- * if you want the limit (max/min) macros for int types.- */-#ifndef __STDC_LIMIT_MACROS-#define __STDC_LIMIT_MACROS 1-#endif--#include <inttypes.h>-typedef int8_t flex_int8_t;-typedef uint8_t flex_uint8_t;-typedef int16_t flex_int16_t;-typedef uint16_t flex_uint16_t;-typedef int32_t flex_int32_t;-typedef uint32_t flex_uint32_t;-#else-typedef signed char flex_int8_t;-typedef short int flex_int16_t;-typedef int flex_int32_t;-typedef unsigned char flex_uint8_t;-typedef unsigned short int flex_uint16_t;-typedef unsigned int flex_uint32_t;--/* Limits of integral types. */-#ifndef INT8_MIN-#define INT8_MIN (-128)-#endif-#ifndef INT16_MIN-#define INT16_MIN (-32767-1)-#endif-#ifndef INT32_MIN-#define INT32_MIN (-2147483647-1)-#endif-#ifndef INT8_MAX-#define INT8_MAX (127)-#endif-#ifndef INT16_MAX-#define INT16_MAX (32767)-#endif-#ifndef INT32_MAX-#define INT32_MAX (2147483647)-#endif-#ifndef UINT8_MAX-#define UINT8_MAX (255U)-#endif-#ifndef UINT16_MAX-#define UINT16_MAX (65535U)-#endif-#ifndef UINT32_MAX-#define UINT32_MAX (4294967295U)-#endif--#ifndef SIZE_MAX-#define SIZE_MAX (~(size_t)0)-#endif--#endif /* ! C99 */--#endif /* ! FLEXINT_H */--/* begin standard C++ headers. */--/* TODO: this is always defined, so inline it */-#define yyconst const--#if defined(__GNUC__) && __GNUC__ >= 3-#define yynoreturn __attribute__((__noreturn__))-#else-#define yynoreturn-#endif--/* Returned upon end-of-file. */-#define YY_NULL 0--/* Promotes a possibly negative, possibly signed char to an- * integer in range [0..255] for use as an array index.- */-#define YY_SC_TO_UI(c) ((YY_CHAR) (c))--/* Enter a start condition. This macro really ought to take a parameter,- * but we do it the disgusting crufty way forced on us by the ()-less- * definition of BEGIN.- */-#define BEGIN (yy_start) = 1 + 2 *-/* Translate the current start state into a value that can be later handed- * to BEGIN to return to the state. The YYSTATE alias is for lex- * compatibility.- */-#define YY_START (((yy_start) - 1) / 2)-#define YYSTATE YY_START-/* Action number for EOF rule of a given start state. */-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)-/* Special action meaning "start processing a new file". */-#define YY_NEW_FILE yyrestart( yyin )-#define YY_END_OF_BUFFER_CHAR 0--/* Size of default input buffer. */-#ifndef YY_BUF_SIZE-#ifdef __ia64__-/* On IA-64, the buffer size is 16k, not 8k.- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.- * Ditto for the __ia64__ case accordingly.- */-#define YY_BUF_SIZE 32768-#else-#define YY_BUF_SIZE 16384-#endif /* __ia64__ */-#endif--/* The state buf must be large enough to hold one state per character in the main buffer.- */-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))--#ifndef YY_TYPEDEF_YY_BUFFER_STATE-#define YY_TYPEDEF_YY_BUFFER_STATE-typedef struct yy_buffer_state *YY_BUFFER_STATE;-#endif--#ifndef YY_TYPEDEF_YY_SIZE_T-#define YY_TYPEDEF_YY_SIZE_T-typedef size_t yy_size_t;-#endif--extern int yyleng;--extern FILE *yyin, *yyout;--#define EOB_ACT_CONTINUE_SCAN 0-#define EOB_ACT_END_OF_FILE 1-#define EOB_ACT_LAST_MATCH 2-- #define YY_LESS_LINENO(n)- #define YY_LINENO_REWIND_TO(ptr)--/* Return all but the first "n" matched characters back to the input stream. */-#define yyless(n) \- do \- { \- /* Undo effects of setting up yytext. */ \- int yyless_macro_arg = (n); \- YY_LESS_LINENO(yyless_macro_arg);\- *yy_cp = (yy_hold_char); \- YY_RESTORE_YY_MORE_OFFSET \- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \- YY_DO_BEFORE_ACTION; /* set up yytext again */ \- } \- while ( 0 )-#define unput(c) yyunput( c, (yytext_ptr) )--#ifndef YY_STRUCT_YY_BUFFER_STATE-#define YY_STRUCT_YY_BUFFER_STATE-struct yy_buffer_state- {- FILE *yy_input_file;-- char *yy_ch_buf; /* input buffer */- char *yy_buf_pos; /* current position in input buffer */-- /* Size of input buffer in bytes, not including room for EOB- * characters.- */- int yy_buf_size;-- /* Number of characters read into yy_ch_buf, not including EOB- * characters.- */- int yy_n_chars;-- /* Whether we "own" the buffer - i.e., we know we created it,- * and can realloc() it to grow it, and should free() it to- * delete it.- */- int yy_is_our_buffer;-- /* Whether this is an "interactive" input source; if so, and- * if we're using stdio for input, then we want to use getc()- * instead of fread(), to make sure we stop fetching input after- * each newline.- */- int yy_is_interactive;-- /* Whether we're considered to be at the beginning of a line.- * If so, '^' rules will be active on the next match, otherwise- * not.- */- int yy_at_bol;-- int yy_bs_lineno; /**< The line count. */- int yy_bs_column; /**< The column count. */-- /* Whether to try to fill the input buffer when we reach the- * end of it.- */- int yy_fill_buffer;-- int yy_buffer_status;--#define YY_BUFFER_NEW 0-#define YY_BUFFER_NORMAL 1- /* When an EOF's been seen but there's still some text to process- * then we mark the buffer as YY_EOF_PENDING, to indicate that we- * shouldn't try reading from the input source any more. We might- * still have a bunch of tokens to match, though, because of- * possible backing-up.- *- * When we actually see the EOF, we change the status to "new"- * (via yyrestart()), so that the user can continue scanning by- * just pointing yyin at a new input file.- */-#define YY_BUFFER_EOF_PENDING 2-- };-#endif /* !YY_STRUCT_YY_BUFFER_STATE */--/* Stack of input buffers. */-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */-static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */--/* We provide macros for accessing buffer states in case in the- * future we want to put the buffer states in a more general- * "scanner state".- *- * Returns the top of the stack, or NULL.- */-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \- : NULL)-/* Same as previous macro, but useful when we know that the buffer stack is not- * NULL or when we need an lvalue. For internal use only.- */-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]--/* yy_hold_char holds the character lost when yytext is formed. */-static char yy_hold_char;-static int yy_n_chars; /* number of characters read into yy_ch_buf */-int yyleng;--/* Points to current character in buffer. */-static char *yy_c_buf_p = NULL;-static int yy_init = 0; /* whether we need to initialize */-static int yy_start = 0; /* start state number */--/* Flag which is used to allow yywrap()'s to do buffer switches- * instead of setting up a fresh yyin. A bit of a hack ...- */-static int yy_did_buffer_switch_on_eof;--void yyrestart ( FILE *input_file );-void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );-YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );-void yy_delete_buffer ( YY_BUFFER_STATE b );-void yy_flush_buffer ( YY_BUFFER_STATE b );-void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );-void yypop_buffer_state ( void );--static void yyensure_buffer_stack ( void );-static void yy_load_buffer_state ( void );-static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );-#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )--YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );-YY_BUFFER_STATE yy_scan_string ( const char *yy_str );-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );--void *yyalloc ( yy_size_t );-void *yyrealloc ( void *, yy_size_t );-void yyfree ( void * );--#define yy_new_buffer yy_create_buffer-#define yy_set_interactive(is_interactive) \- { \- if ( ! YY_CURRENT_BUFFER ){ \- yyensure_buffer_stack (); \- YY_CURRENT_BUFFER_LVALUE = \- yy_create_buffer( yyin, YY_BUF_SIZE ); \- } \- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \- }-#define yy_set_bol(at_bol) \- { \- if ( ! YY_CURRENT_BUFFER ){\- yyensure_buffer_stack (); \- YY_CURRENT_BUFFER_LVALUE = \- yy_create_buffer( yyin, YY_BUF_SIZE ); \- } \- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \- }-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)--/* Begin user sect3 */--#define yywrap() (/*CONSTCOND*/1)-#define YY_SKIP_YYWRAP-typedef flex_uint8_t YY_CHAR;--FILE *yyin = NULL, *yyout = NULL;--typedef int yy_state_type;--extern int yylineno;-int yylineno = 1;--extern char *yytext;-#ifdef yytext_ptr-#undef yytext_ptr-#endif-#define yytext_ptr yytext--static yy_state_type yy_get_previous_state ( void );-static yy_state_type yy_try_NUL_trans ( yy_state_type current_state );-static int yy_get_next_buffer ( void );-static void yynoreturn yy_fatal_error ( const char* msg );--/* Done after the current pattern has been matched and before the- * corresponding action - sets up yytext.- */-#define YY_DO_BEFORE_ACTION \- (yytext_ptr) = yy_bp; \- yyleng = (int) (yy_cp - yy_bp); \- (yy_hold_char) = *yy_cp; \- *yy_cp = '\0'; \- (yy_c_buf_p) = yy_cp;-#define YY_NUM_RULES 23-#define YY_END_OF_BUFFER 24-/* This struct is not used in this scanner,- but its presence is necessary. */-struct yy_trans_info- {- flex_int32_t yy_verify;- flex_int32_t yy_nxt;- };-static const flex_int16_t yy_accept[64] =- { 0,- 0, 0, 24, 23, 1, 20, 23, 11, 12, 19,- 23, 3, 4, 18, 17, 21, 15, 16, 10, 10,- 10, 10, 10, 10, 13, 14, 1, 0, 0, 0,- 4, 10, 10, 10, 10, 10, 10, 22, 0, 2,- 10, 10, 6, 6, 10, 10, 10, 10, 8, 8,- 10, 9, 9, 10, 10, 10, 7, 7, 10, 10,- 5, 5, 0- } ;--static const YY_CHAR yy_ec[256] =- { 0,- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 2, 4, 1, 1, 1, 1, 1, 5, 6,- 7, 1, 1, 8, 1, 1, 9, 10, 11, 12,- 12, 12, 12, 12, 12, 12, 12, 13, 14, 1,- 15, 1, 1, 1, 16, 16, 16, 17, 17, 16,- 16, 16, 17, 16, 16, 17, 16, 16, 16, 16,- 16, 17, 16, 17, 16, 16, 16, 16, 16, 16,- 18, 19, 20, 1, 21, 1, 22, 21, 23, 21,-- 24, 25, 21, 26, 27, 21, 21, 28, 21, 29,- 30, 21, 21, 31, 32, 33, 34, 35, 36, 21,- 21, 21, 37, 1, 38, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1- } ;--static const YY_CHAR yy_meta[39] =- { 0,- 1, 1, 2, 1, 3, 1, 1, 1, 1, 4,- 5, 5, 1, 1, 1, 5, 5, 1, 1, 1,- 5, 5, 5, 5, 4, 5, 5, 5, 4, 5,- 4, 5, 4, 5, 4, 5, 1, 1- } ;--static const flex_int16_t yy_base[68] =- { 0,- 0, 0, 268, 269, 37, 269, 248, 269, 269, 269,- 257, 31, 34, 269, 269, 269, 269, 269, 0, 237,- 230, 238, 240, 235, 269, 269, 45, 255, 254, 255,- 39, 0, 225, 227, 51, 224, 227, 269, 250, 269,- 228, 228, 269, 0, 87, 222, 123, 216, 269, 0,- 224, 269, 0, 220, 159, 216, 269, 0, 204, 195,- 269, 0, 269, 231, 233, 236, 240- } ;--static const flex_int16_t yy_def[68] =- { 0,- 63, 1, 63, 63, 63, 63, 64, 63, 63, 63,- 63, 63, 63, 63, 63, 63, 63, 63, 65, 65,- 65, 65, 65, 65, 63, 63, 63, 63, 66, 67,- 63, 65, 65, 65, 63, 65, 65, 63, 67, 63,- 65, 65, 63, 65, 63, 65, 63, 65, 63, 65,- 65, 63, 65, 65, 63, 65, 63, 65, 65, 63,- 63, 65, 0, 63, 63, 63, 63- } ;--static const flex_int16_t yy_nxt[308] =- { 0,- 4, 5, 5, 6, 7, 8, 9, 10, 11, 12,- 12, 13, 14, 15, 16, 4, 4, 17, 4, 18,- 19, 19, 19, 20, 21, 19, 22, 19, 19, 19,- 19, 19, 19, 19, 23, 24, 25, 26, 27, 27,- 31, 31, 31, 31, 31, 31, 27, 27, 31, 31,- 31, 43, 43, 43, 43, 43, 43, 43, 43, 43,- 44, 44, 44, 43, 43, 43, 44, 32, 43, 43,- 43, 44, 44, 44, 44, 44, 44, 44, 44, 44,- 44, 44, 44, 44, 44, 44, 44, 49, 49, 49,- 49, 49, 49, 49, 49, 49, 50, 50, 50, 49,-- 49, 49, 50, 32, 49, 49, 49, 50, 50, 50,- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,- 50, 50, 50, 52, 52, 52, 52, 52, 52, 52,- 52, 52, 53, 53, 53, 52, 52, 52, 53, 32,- 52, 52, 52, 53, 53, 53, 53, 53, 53, 53,- 53, 53, 53, 53, 53, 53, 53, 53, 53, 57,- 57, 57, 57, 57, 57, 57, 57, 57, 58, 58,- 58, 57, 57, 57, 58, 32, 57, 57, 57, 58,- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,- 58, 58, 58, 58, 58, 61, 61, 61, 61, 61,-- 61, 61, 61, 61, 62, 62, 62, 61, 61, 61,- 62, 32, 61, 61, 61, 62, 62, 62, 62, 62,- 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,- 62, 28, 60, 28, 28, 28, 32, 32, 28, 28,- 39, 39, 39, 39, 39, 59, 56, 55, 54, 51,- 48, 47, 40, 46, 45, 42, 41, 40, 38, 38,- 37, 36, 35, 34, 33, 30, 29, 63, 3, 63,- 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,- 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,- 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,-- 63, 63, 63, 63, 63, 63, 63- } ;--static const flex_int16_t yy_chk[308] =- { 0,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,- 1, 1, 1, 1, 1, 1, 1, 1, 5, 5,- 12, 12, 12, 13, 13, 13, 27, 27, 31, 31,- 31, 35, 35, 35, 35, 35, 35, 35, 35, 35,- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,- 35, 35, 35, 35, 35, 35, 35, 45, 45, 45,- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,-- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,- 45, 45, 45, 47, 47, 47, 47, 47, 47, 47,- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,- 47, 47, 47, 47, 47, 47, 47, 47, 47, 55,- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,- 55, 55, 55, 55, 55, 60, 60, 60, 60, 60,-- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,- 60, 64, 59, 64, 64, 64, 65, 65, 66, 66,- 67, 67, 67, 67, 67, 56, 54, 51, 48, 46,- 42, 41, 39, 37, 36, 34, 33, 30, 29, 28,- 24, 23, 22, 21, 20, 11, 7, 3, 63, 63,- 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,- 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,- 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,-- 63, 63, 63, 63, 63, 63, 63- } ;--static yy_state_type yy_last_accepting_state;-static char *yy_last_accepting_cpos;--extern int yy_flex_debug;-int yy_flex_debug = 0;--/* The intent behind this definition is that it'll catch- * any uses of REJECT which flex missed.- */-#define REJECT reject_used_but_not_detected-#define yymore() yymore_used_but_not_detected-#define YY_MORE_ADJ 0-#define YY_RESTORE_YY_MORE_OFFSET-char *yytext;-#line 1 "Nandlang.l"-#line 3 "Nandlang.l"-#include "Nandlang.tab.h"-#include "stdio.h"-void set_input_string(const char* in);-void end_lexical_scan(void);-#line 536 "lex.yy.c"-#line 537 "lex.yy.c"--#define INITIAL 0--#ifndef YY_NO_UNISTD_H-/* Special case for "unistd.h", since it is non-ANSI. We include it way- * down here because we want the user's section 1 to have been scanned first.- * The user has a chance to override it with an option.- */-#include <unistd.h>-#endif--#ifndef YY_EXTRA_TYPE-#define YY_EXTRA_TYPE void *-#endif--static int yy_init_globals ( void );--/* Accessor methods to globals.- These are made visible to non-reentrant scanners for convenience. */--int yylex_destroy ( void );--int yyget_debug ( void );--void yyset_debug ( int debug_flag );--YY_EXTRA_TYPE yyget_extra ( void );--void yyset_extra ( YY_EXTRA_TYPE user_defined );--FILE *yyget_in ( void );--void yyset_in ( FILE * _in_str );--FILE *yyget_out ( void );--void yyset_out ( FILE * _out_str );-- int yyget_leng ( void );--char *yyget_text ( void );--int yyget_lineno ( void );--void yyset_lineno ( int _line_number );--/* Macros after this point can all be overridden by user definitions in- * section 1.- */--#ifndef YY_SKIP_YYWRAP-#ifdef __cplusplus-extern "C" int yywrap ( void );-#else-extern int yywrap ( void );-#endif-#endif--#ifndef YY_NO_UNPUT-- static void yyunput ( int c, char *buf_ptr );--#endif--#ifndef yytext_ptr-static void yy_flex_strncpy ( char *, const char *, int );-#endif--#ifdef YY_NEED_STRLEN-static int yy_flex_strlen ( const char * );-#endif--#ifndef YY_NO_INPUT-#ifdef __cplusplus-static int yyinput ( void );-#else-static int input ( void );-#endif--#endif--/* Amount of stuff to slurp up with each read. */-#ifndef YY_READ_BUF_SIZE-#ifdef __ia64__-/* On IA-64, the buffer size is 16k, not 8k */-#define YY_READ_BUF_SIZE 16384-#else-#define YY_READ_BUF_SIZE 8192-#endif /* __ia64__ */-#endif--/* Copy whatever the last rule matched to the standard output. */-#ifndef ECHO-/* This used to be an fputs(), but since the string might contain NUL's,- * we now use fwrite().- */-#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)-#endif--/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,- * is returned in "result".- */-#ifndef YY_INPUT-#define YY_INPUT(buf,result,max_size) \- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \- { \- int c = '*'; \- int n; \- for ( n = 0; n < max_size && \- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \- buf[n] = (char) c; \- if ( c == '\n' ) \- buf[n++] = (char) c; \- if ( c == EOF && ferror( yyin ) ) \- YY_FATAL_ERROR( "input in flex scanner failed" ); \- result = n; \- } \- else \- { \- errno=0; \- while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \- { \- if( errno != EINTR) \- { \- YY_FATAL_ERROR( "input in flex scanner failed" ); \- break; \- } \- errno=0; \- clearerr(yyin); \- } \- }\-\--#endif--/* No semi-colon after return; correct usage is to write "yyterminate();" -- * we don't want an extra ';' after the "return" because that will cause- * some compilers to complain about unreachable statements.- */-#ifndef yyterminate-#define yyterminate() return YY_NULL-#endif--/* Number of entries by which start-condition stack grows. */-#ifndef YY_START_STACK_INCR-#define YY_START_STACK_INCR 25-#endif--/* Report a fatal error. */-#ifndef YY_FATAL_ERROR-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )-#endif--/* end tables serialization structures and prototypes */--/* Default declaration of generated scanner - a define so the user can- * easily add parameters.- */-#ifndef YY_DECL-#define YY_DECL_IS_OURS 1--extern int yylex (void);--#define YY_DECL int yylex (void)-#endif /* !YY_DECL */--/* Code executed at the beginning of each rule, after yytext and yyleng- * have been set up.- */-#ifndef YY_USER_ACTION-#define YY_USER_ACTION-#endif--/* Code executed at the end of each rule. */-#ifndef YY_BREAK-#define YY_BREAK /*LINTED*/break;-#endif--#define YY_RULE_SETUP \- YY_USER_ACTION--/** The main scanner function which does all the work.- */-YY_DECL-{- yy_state_type yy_current_state;- char *yy_cp, *yy_bp;- int yy_act;-- if ( !(yy_init) )- {- (yy_init) = 1;--#ifdef YY_USER_INIT- YY_USER_INIT;-#endif-- if ( ! (yy_start) )- (yy_start) = 1; /* first start state */-- if ( ! yyin )- yyin = stdin;-- if ( ! yyout )- yyout = stdout;-- if ( ! YY_CURRENT_BUFFER ) {- yyensure_buffer_stack ();- YY_CURRENT_BUFFER_LVALUE =- yy_create_buffer( yyin, YY_BUF_SIZE );- }-- yy_load_buffer_state( );- }-- {-#line 14 "Nandlang.l"--#line 756 "lex.yy.c"-- while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */- {- yy_cp = (yy_c_buf_p);-- /* Support of yytext. */- *yy_cp = (yy_hold_char);-- /* yy_bp points to the position in yy_ch_buf of the start of- * the current run.- */- yy_bp = yy_cp;-- yy_current_state = (yy_start);-yy_match:- do- {- YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;- if ( yy_accept[yy_current_state] )- {- (yy_last_accepting_state) = yy_current_state;- (yy_last_accepting_cpos) = yy_cp;- }- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )- {- yy_current_state = (int) yy_def[yy_current_state];- if ( yy_current_state >= 64 )- yy_c = yy_meta[yy_c];- }- yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];- ++yy_cp;- }- while ( yy_base[yy_current_state] != 269 );--yy_find_action:- yy_act = yy_accept[yy_current_state];- if ( yy_act == 0 )- { /* have to back up */- yy_cp = (yy_last_accepting_cpos);- yy_current_state = (yy_last_accepting_state);- yy_act = yy_accept[yy_current_state];- }-- YY_DO_BEFORE_ACTION;--do_action: /* This label is used only to access EOF actions. */-- switch ( yy_act )- { /* beginning of action switch */- case 0: /* must back up */- /* undo the effects of YY_DO_BEFORE_ACTION */- *yy_cp = (yy_hold_char);- yy_cp = (yy_last_accepting_cpos);- yy_current_state = (yy_last_accepting_state);- goto yy_find_action;--case 1:-/* rule 1 can match eol */-YY_RULE_SETUP-#line 15 "Nandlang.l"-;- YY_BREAK-case 2:-/* rule 2 can match eol */-YY_RULE_SETUP-#line 16 "Nandlang.l"-;- YY_BREAK-case 3:-YY_RULE_SETUP-#line 17 "Nandlang.l"-return BIT;- YY_BREAK-case 4:-YY_RULE_SETUP-#line 18 "Nandlang.l"-return NAT;- YY_BREAK-case 5:-/* rule 5 can match eol */-YY_RULE_SETUP-#line 19 "Nandlang.l"-return FUNCTION;- YY_BREAK-case 6:-/* rule 6 can match eol */-YY_RULE_SETUP-#line 20 "Nandlang.l"-return IF;- YY_BREAK-case 7:-/* rule 7 can match eol */-YY_RULE_SETUP-#line 21 "Nandlang.l"-return WHILE;- YY_BREAK-case 8:-/* rule 8 can match eol */-YY_RULE_SETUP-#line 22 "Nandlang.l"-return VAR;- YY_BREAK-case 9:-/* rule 9 can match eol */-YY_RULE_SETUP-#line 23 "Nandlang.l"-return ELSE;- YY_BREAK-case 10:-YY_RULE_SETUP-#line 24 "Nandlang.l"-return IDENTIFIER;- YY_BREAK-case 11:-YY_RULE_SETUP-#line 25 "Nandlang.l"-return '(';- YY_BREAK-case 12:-YY_RULE_SETUP-#line 26 "Nandlang.l"-return ')';- YY_BREAK-case 13:-YY_RULE_SETUP-#line 27 "Nandlang.l"-return '{';- YY_BREAK-case 14:-YY_RULE_SETUP-#line 28 "Nandlang.l"-return '}';- YY_BREAK-case 15:-YY_RULE_SETUP-#line 29 "Nandlang.l"-return '[';- YY_BREAK-case 16:-YY_RULE_SETUP-#line 30 "Nandlang.l"-return ']';- YY_BREAK-case 17:-YY_RULE_SETUP-#line 31 "Nandlang.l"-return ';';- YY_BREAK-case 18:-YY_RULE_SETUP-#line 32 "Nandlang.l"-return ':';- YY_BREAK-case 19:-YY_RULE_SETUP-#line 33 "Nandlang.l"-return ',';- YY_BREAK-case 20:-YY_RULE_SETUP-#line 34 "Nandlang.l"-return '!';- YY_BREAK-case 21:-YY_RULE_SETUP-#line 35 "Nandlang.l"-return '=';- YY_BREAK-case 22:-YY_RULE_SETUP-#line 36 "Nandlang.l"-return CHAR;- YY_BREAK-case 23:-YY_RULE_SETUP-#line 37 "Nandlang.l"-ECHO;- YY_BREAK-#line 935 "lex.yy.c"-case YY_STATE_EOF(INITIAL):- yyterminate();-- case YY_END_OF_BUFFER:- {- /* Amount of text matched not including the EOB char. */- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;-- /* Undo the effects of YY_DO_BEFORE_ACTION. */- *yy_cp = (yy_hold_char);- YY_RESTORE_YY_MORE_OFFSET-- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )- {- /* We're scanning a new file or input source. It's- * possible that this happened because the user- * just pointed yyin at a new source and called- * yylex(). If so, then we have to assure- * consistency between YY_CURRENT_BUFFER and our- * globals. Here is the right place to do so, because- * this is the first action (other than possibly a- * back-up) that will match for the new input source.- */- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;- }-- /* Note that here we test for yy_c_buf_p "<=" to the position- * of the first EOB in the buffer, since yy_c_buf_p will- * already have been incremented past the NUL character- * (since all states make transitions on EOB to the- * end-of-buffer state). Contrast this with the test- * in input().- */- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )- { /* This was really a NUL. */- yy_state_type yy_next_state;-- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;-- yy_current_state = yy_get_previous_state( );-- /* Okay, we're now positioned to make the NUL- * transition. We couldn't have- * yy_get_previous_state() go ahead and do it- * for us because it doesn't know how to deal- * with the possibility of jamming (and we don't- * want to build jamming into it because then it- * will run more slowly).- */-- yy_next_state = yy_try_NUL_trans( yy_current_state );-- yy_bp = (yytext_ptr) + YY_MORE_ADJ;-- if ( yy_next_state )- {- /* Consume the NUL. */- yy_cp = ++(yy_c_buf_p);- yy_current_state = yy_next_state;- goto yy_match;- }-- else- {- yy_cp = (yy_c_buf_p);- goto yy_find_action;- }- }-- else switch ( yy_get_next_buffer( ) )- {- case EOB_ACT_END_OF_FILE:- {- (yy_did_buffer_switch_on_eof) = 0;-- if ( yywrap( ) )- {- /* Note: because we've taken care in- * yy_get_next_buffer() to have set up- * yytext, we can now set up- * yy_c_buf_p so that if some total- * hoser (like flex itself) wants to- * call the scanner after we return the- * YY_NULL, it'll still work - another- * YY_NULL will get returned.- */- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;-- yy_act = YY_STATE_EOF(YY_START);- goto do_action;- }-- else- {- if ( ! (yy_did_buffer_switch_on_eof) )- YY_NEW_FILE;- }- break;- }-- case EOB_ACT_CONTINUE_SCAN:- (yy_c_buf_p) =- (yytext_ptr) + yy_amount_of_matched_text;-- yy_current_state = yy_get_previous_state( );-- yy_cp = (yy_c_buf_p);- yy_bp = (yytext_ptr) + YY_MORE_ADJ;- goto yy_match;-- case EOB_ACT_LAST_MATCH:- (yy_c_buf_p) =- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];-- yy_current_state = yy_get_previous_state( );-- yy_cp = (yy_c_buf_p);- yy_bp = (yytext_ptr) + YY_MORE_ADJ;- goto yy_find_action;- }- break;- }-- default:- YY_FATAL_ERROR(- "fatal flex scanner internal error--no action found" );- } /* end of action switch */- } /* end of scanning one token */- } /* end of user's declarations */-} /* end of yylex */--/* yy_get_next_buffer - try to read in a new buffer- *- * Returns a code representing an action:- * EOB_ACT_LAST_MATCH -- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position- * EOB_ACT_END_OF_FILE - end of file- */-static int yy_get_next_buffer (void)-{- char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;- char *source = (yytext_ptr);- int number_to_move, i;- int ret_val;-- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )- YY_FATAL_ERROR(- "fatal flex scanner internal error--end of buffer missed" );-- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )- { /* Don't try to fill the buffer, so this is an EOF. */- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )- {- /* We matched a single character, the EOB, so- * treat this as a final EOF.- */- return EOB_ACT_END_OF_FILE;- }-- else- {- /* We matched some text prior to the EOB, first- * process it.- */- return EOB_ACT_LAST_MATCH;- }- }-- /* Try to read more data. */-- /* First move last chars to start of buffer. */- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);-- for ( i = 0; i < number_to_move; ++i )- *(dest++) = *(source++);-- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )- /* don't do the read, it's not guaranteed to return an EOF,- * just force an EOF- */- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;-- else- {- int num_to_read =- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;-- while ( num_to_read <= 0 )- { /* Not enough room in the buffer - grow it. */-- /* just a shorter name for the current buffer */- YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;-- int yy_c_buf_p_offset =- (int) ((yy_c_buf_p) - b->yy_ch_buf);-- if ( b->yy_is_our_buffer )- {- int new_size = b->yy_buf_size * 2;-- if ( new_size <= 0 )- b->yy_buf_size += b->yy_buf_size / 8;- else- b->yy_buf_size *= 2;-- b->yy_ch_buf = (char *)- /* Include room in for 2 EOB chars. */- yyrealloc( (void *) b->yy_ch_buf,- (yy_size_t) (b->yy_buf_size + 2) );- }- else- /* Can't grow it, we don't own it. */- b->yy_ch_buf = NULL;-- if ( ! b->yy_ch_buf )- YY_FATAL_ERROR(- "fatal error - scanner input buffer overflow" );-- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];-- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -- number_to_move - 1;-- }-- if ( num_to_read > YY_READ_BUF_SIZE )- num_to_read = YY_READ_BUF_SIZE;-- /* Read in more data. */- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),- (yy_n_chars), num_to_read );-- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);- }-- if ( (yy_n_chars) == 0 )- {- if ( number_to_move == YY_MORE_ADJ )- {- ret_val = EOB_ACT_END_OF_FILE;- yyrestart( yyin );- }-- else- {- ret_val = EOB_ACT_LAST_MATCH;- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =- YY_BUFFER_EOF_PENDING;- }- }-- else- ret_val = EOB_ACT_CONTINUE_SCAN;-- if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {- /* Extend the array by 50%, plus the number we really need. */- int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(- (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size );- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );- /* "- 2" to take care of EOB's */- YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);- }-- (yy_n_chars) += number_to_move;- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;-- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];-- return ret_val;-}--/* yy_get_previous_state - get the state just before the EOB char was reached */-- static yy_state_type yy_get_previous_state (void)-{- yy_state_type yy_current_state;- char *yy_cp;-- yy_current_state = (yy_start);-- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )- {- YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);- if ( yy_accept[yy_current_state] )- {- (yy_last_accepting_state) = yy_current_state;- (yy_last_accepting_cpos) = yy_cp;- }- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )- {- yy_current_state = (int) yy_def[yy_current_state];- if ( yy_current_state >= 64 )- yy_c = yy_meta[yy_c];- }- yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];- }-- return yy_current_state;-}--/* yy_try_NUL_trans - try to make a transition on the NUL character- *- * synopsis- * next_state = yy_try_NUL_trans( current_state );- */- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )-{- int yy_is_jam;- char *yy_cp = (yy_c_buf_p);-- YY_CHAR yy_c = 1;- if ( yy_accept[yy_current_state] )- {- (yy_last_accepting_state) = yy_current_state;- (yy_last_accepting_cpos) = yy_cp;- }- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )- {- yy_current_state = (int) yy_def[yy_current_state];- if ( yy_current_state >= 64 )- yy_c = yy_meta[yy_c];- }- yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];- yy_is_jam = (yy_current_state == 63);-- return yy_is_jam ? 0 : yy_current_state;-}--#ifndef YY_NO_UNPUT-- static void yyunput (int c, char * yy_bp )-{- char *yy_cp;-- yy_cp = (yy_c_buf_p);-- /* undo effects of setting up yytext */- *yy_cp = (yy_hold_char);-- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )- { /* need to shift things up to make room */- /* +2 for EOB chars. */- int number_to_move = (yy_n_chars) + 2;- char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];- char *source =- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];-- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )- *--dest = *--source;-- yy_cp += (int) (dest - source);- yy_bp += (int) (dest - source);- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =- (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;-- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )- YY_FATAL_ERROR( "flex scanner push-back overflow" );- }-- *--yy_cp = (char) c;-- (yytext_ptr) = yy_bp;- (yy_hold_char) = *yy_cp;- (yy_c_buf_p) = yy_cp;-}--#endif--#ifndef YY_NO_INPUT-#ifdef __cplusplus- static int yyinput (void)-#else- static int input (void)-#endif--{- int c;-- *(yy_c_buf_p) = (yy_hold_char);-- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )- {- /* yy_c_buf_p now points to the character we want to return.- * If this occurs *before* the EOB characters, then it's a- * valid NUL; if not, then we've hit the end of the buffer.- */- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )- /* This was really a NUL. */- *(yy_c_buf_p) = '\0';-- else- { /* need more input */- int offset = (int) ((yy_c_buf_p) - (yytext_ptr));- ++(yy_c_buf_p);-- switch ( yy_get_next_buffer( ) )- {- case EOB_ACT_LAST_MATCH:- /* This happens because yy_g_n_b()- * sees that we've accumulated a- * token and flags that we need to- * try matching the token before- * proceeding. But for input(),- * there's no matching to consider.- * So convert the EOB_ACT_LAST_MATCH- * to EOB_ACT_END_OF_FILE.- */-- /* Reset buffer status. */- yyrestart( yyin );-- /*FALLTHROUGH*/-- case EOB_ACT_END_OF_FILE:- {- if ( yywrap( ) )- return 0;-- if ( ! (yy_did_buffer_switch_on_eof) )- YY_NEW_FILE;-#ifdef __cplusplus- return yyinput();-#else- return input();-#endif- }-- case EOB_ACT_CONTINUE_SCAN:- (yy_c_buf_p) = (yytext_ptr) + offset;- break;- }- }- }-- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */- *(yy_c_buf_p) = '\0'; /* preserve yytext */- (yy_hold_char) = *++(yy_c_buf_p);-- return c;-}-#endif /* ifndef YY_NO_INPUT */--/** Immediately switch to a different input stream.- * @param input_file A readable stream.- *- * @note This function does not reset the start condition to @c INITIAL .- */- void yyrestart (FILE * input_file )-{-- if ( ! YY_CURRENT_BUFFER ){- yyensure_buffer_stack ();- YY_CURRENT_BUFFER_LVALUE =- yy_create_buffer( yyin, YY_BUF_SIZE );- }-- yy_init_buffer( YY_CURRENT_BUFFER, input_file );- yy_load_buffer_state( );-}--/** Switch to a different input buffer.- * @param new_buffer The new input buffer.- *- */- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )-{-- /* TODO. We should be able to replace this entire function body- * with- * yypop_buffer_state();- * yypush_buffer_state(new_buffer);- */- yyensure_buffer_stack ();- if ( YY_CURRENT_BUFFER == new_buffer )- return;-- if ( YY_CURRENT_BUFFER )- {- /* Flush out information for old buffer. */- *(yy_c_buf_p) = (yy_hold_char);- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);- }-- YY_CURRENT_BUFFER_LVALUE = new_buffer;- yy_load_buffer_state( );-- /* We don't actually know whether we did this switch during- * EOF (yywrap()) processing, but the only time this flag- * is looked at is after yywrap() is called, so it's safe- * to go ahead and always set it.- */- (yy_did_buffer_switch_on_eof) = 1;-}--static void yy_load_buffer_state (void)-{- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;- (yy_hold_char) = *(yy_c_buf_p);-}--/** Allocate and initialize an input buffer state.- * @param file A readable stream.- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.- *- * @return the allocated buffer state.- */- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )-{- YY_BUFFER_STATE b;-- b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );- if ( ! b )- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );-- b->yy_buf_size = size;-- /* yy_ch_buf has to be 2 characters longer than the size given because- * we need to put in 2 end-of-buffer characters.- */- b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) );- if ( ! b->yy_ch_buf )- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );-- b->yy_is_our_buffer = 1;-- yy_init_buffer( b, file );-- return b;-}--/** Destroy the buffer.- * @param b a buffer created with yy_create_buffer()- *- */- void yy_delete_buffer (YY_BUFFER_STATE b )-{-- if ( ! b )- return;-- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;-- if ( b->yy_is_our_buffer )- yyfree( (void *) b->yy_ch_buf );-- yyfree( (void *) b );-}--/* Initializes or reinitializes a buffer.- * This function is sometimes called more than once on the same buffer,- * such as during a yyrestart() or at EOF.- */- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )--{- int oerrno = errno;-- yy_flush_buffer( b );-- b->yy_input_file = file;- b->yy_fill_buffer = 1;-- /* If b is the current buffer, then yy_init_buffer was _probably_- * called from yyrestart() or through yy_get_next_buffer.- * In that case, we don't want to reset the lineno or column.- */- if (b != YY_CURRENT_BUFFER){- b->yy_bs_lineno = 1;- b->yy_bs_column = 0;- }-- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;-- errno = oerrno;-}--/** Discard all buffered characters. On the next scan, YY_INPUT will be called.- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.- *- */- void yy_flush_buffer (YY_BUFFER_STATE b )-{- if ( ! b )- return;-- b->yy_n_chars = 0;-- /* We always need two end-of-buffer characters. The first causes- * a transition to the end-of-buffer state. The second causes- * a jam in that state.- */- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;-- b->yy_buf_pos = &b->yy_ch_buf[0];-- b->yy_at_bol = 1;- b->yy_buffer_status = YY_BUFFER_NEW;-- if ( b == YY_CURRENT_BUFFER )- yy_load_buffer_state( );-}--/** Pushes the new state onto the stack. The new state becomes- * the current state. This function will allocate the stack- * if necessary.- * @param new_buffer The new state.- *- */-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )-{- if (new_buffer == NULL)- return;-- yyensure_buffer_stack();-- /* This block is copied from yy_switch_to_buffer. */- if ( YY_CURRENT_BUFFER )- {- /* Flush out information for old buffer. */- *(yy_c_buf_p) = (yy_hold_char);- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);- }-- /* Only push if top exists. Otherwise, replace top. */- if (YY_CURRENT_BUFFER)- (yy_buffer_stack_top)++;- YY_CURRENT_BUFFER_LVALUE = new_buffer;-- /* copied from yy_switch_to_buffer. */- yy_load_buffer_state( );- (yy_did_buffer_switch_on_eof) = 1;-}--/** Removes and deletes the top of the stack, if present.- * The next element becomes the new top.- *- */-void yypop_buffer_state (void)-{- if (!YY_CURRENT_BUFFER)- return;-- yy_delete_buffer(YY_CURRENT_BUFFER );- YY_CURRENT_BUFFER_LVALUE = NULL;- if ((yy_buffer_stack_top) > 0)- --(yy_buffer_stack_top);-- if (YY_CURRENT_BUFFER) {- yy_load_buffer_state( );- (yy_did_buffer_switch_on_eof) = 1;- }-}--/* Allocates the stack if it does not exist.- * Guarantees space for at least one push.- */-static void yyensure_buffer_stack (void)-{- yy_size_t num_to_alloc;-- if (!(yy_buffer_stack)) {-- /* First allocation is just for 2 elements, since we don't know if this- * scanner will even need a stack. We use 2 instead of 1 to avoid an- * immediate realloc on the next call.- */- num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc- (num_to_alloc * sizeof(struct yy_buffer_state*)- );- if ( ! (yy_buffer_stack) )- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );-- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));-- (yy_buffer_stack_max) = num_to_alloc;- (yy_buffer_stack_top) = 0;- return;- }-- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){-- /* Increase the buffer to prepare for a possible push. */- yy_size_t grow_size = 8 /* arbitrary grow size */;-- num_to_alloc = (yy_buffer_stack_max) + grow_size;- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc- ((yy_buffer_stack),- num_to_alloc * sizeof(struct yy_buffer_state*)- );- if ( ! (yy_buffer_stack) )- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );-- /* zero only the new slots.*/- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));- (yy_buffer_stack_max) = num_to_alloc;- }-}--/** Setup the input buffer state to scan directly from a user-specified character buffer.- * @param base the character buffer- * @param size the size in bytes of the character buffer- *- * @return the newly allocated buffer state object.- */-YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )-{- YY_BUFFER_STATE b;-- if ( size < 2 ||- base[size-2] != YY_END_OF_BUFFER_CHAR ||- base[size-1] != YY_END_OF_BUFFER_CHAR )- /* They forgot to leave room for the EOB's. */- return NULL;-- b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );- if ( ! b )- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );-- b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */- b->yy_buf_pos = b->yy_ch_buf = base;- b->yy_is_our_buffer = 0;- b->yy_input_file = NULL;- b->yy_n_chars = b->yy_buf_size;- b->yy_is_interactive = 0;- b->yy_at_bol = 1;- b->yy_fill_buffer = 0;- b->yy_buffer_status = YY_BUFFER_NEW;-- yy_switch_to_buffer( b );-- return b;-}--/** Setup the input buffer state to scan a string. The next call to yylex() will- * scan from a @e copy of @a str.- * @param yystr a NUL-terminated string to scan- *- * @return the newly allocated buffer state object.- * @note If you want to scan bytes that may contain NUL values, then use- * yy_scan_bytes() instead.- */-YY_BUFFER_STATE yy_scan_string (const char * yystr )-{-- return yy_scan_bytes( yystr, (int) strlen(yystr) );-}--/** Setup the input buffer state to scan the given bytes. The next call to yylex() will- * scan from a @e copy of @a bytes.- * @param yybytes the byte buffer to scan- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.- *- * @return the newly allocated buffer state object.- */-YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )-{- YY_BUFFER_STATE b;- char *buf;- yy_size_t n;- int i;-- /* Get memory for full buffer, including space for trailing EOB's. */- n = (yy_size_t) (_yybytes_len + 2);- buf = (char *) yyalloc( n );- if ( ! buf )- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );-- for ( i = 0; i < _yybytes_len; ++i )- buf[i] = yybytes[i];-- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;-- b = yy_scan_buffer( buf, n );- if ( ! b )- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );-- /* It's okay to grow etc. this buffer, and we should throw it- * away when we're done.- */- b->yy_is_our_buffer = 1;-- return b;-}--#ifndef YY_EXIT_FAILURE-#define YY_EXIT_FAILURE 2-#endif--static void yynoreturn yy_fatal_error (const char* msg )-{- fprintf( stderr, "%s\n", msg );- exit( YY_EXIT_FAILURE );-}--/* Redefine yyless() so it works in section 3 code. */--#undef yyless-#define yyless(n) \- do \- { \- /* Undo effects of setting up yytext. */ \- int yyless_macro_arg = (n); \- YY_LESS_LINENO(yyless_macro_arg);\- yytext[yyleng] = (yy_hold_char); \- (yy_c_buf_p) = yytext + yyless_macro_arg; \- (yy_hold_char) = *(yy_c_buf_p); \- *(yy_c_buf_p) = '\0'; \- yyleng = yyless_macro_arg; \- } \- while ( 0 )--/* Accessor methods (get/set functions) to struct members. */--/** Get the current line number.- *- */-int yyget_lineno (void)-{-- return yylineno;-}--/** Get the input stream.- *- */-FILE *yyget_in (void)-{- return yyin;-}--/** Get the output stream.- *- */-FILE *yyget_out (void)-{- return yyout;-}--/** Get the length of the current token.- *- */-int yyget_leng (void)-{- return yyleng;-}--/** Get the current token.- *- */--char *yyget_text (void)-{- return yytext;-}--/** Set the current line number.- * @param _line_number line number- *- */-void yyset_lineno (int _line_number )-{-- yylineno = _line_number;-}--/** Set the input stream. This does not discard the current- * input buffer.- * @param _in_str A readable stream.- *- * @see yy_switch_to_buffer- */-void yyset_in (FILE * _in_str )-{- yyin = _in_str ;-}--void yyset_out (FILE * _out_str )-{- yyout = _out_str ;-}--int yyget_debug (void)-{- return yy_flex_debug;-}--void yyset_debug (int _bdebug )-{- yy_flex_debug = _bdebug ;-}--static int yy_init_globals (void)-{- /* Initialization is the same as for the non-reentrant scanner.- * This function is called from yylex_destroy(), so don't allocate here.- */-- (yy_buffer_stack) = NULL;- (yy_buffer_stack_top) = 0;- (yy_buffer_stack_max) = 0;- (yy_c_buf_p) = NULL;- (yy_init) = 0;- (yy_start) = 0;--/* Defined in main.c */-#ifdef YY_STDINIT- yyin = stdin;- yyout = stdout;-#else- yyin = NULL;- yyout = NULL;-#endif-- /* For future reference: Set errno on error, since we are called by- * yylex_init()- */- return 0;-}--/* yylex_destroy is for both reentrant and non-reentrant scanners. */-int yylex_destroy (void)-{-- /* Pop the buffer stack, destroying each element. */- while(YY_CURRENT_BUFFER){- yy_delete_buffer( YY_CURRENT_BUFFER );- YY_CURRENT_BUFFER_LVALUE = NULL;- yypop_buffer_state();- }-- /* Destroy the stack itself. */- yyfree((yy_buffer_stack) );- (yy_buffer_stack) = NULL;-- /* Reset the globals. This is important in a non-reentrant scanner so the next time- * yylex() is called, initialization will occur. */- yy_init_globals( );-- return 0;-}--/*- * Internal utility routines.- */--#ifndef yytext_ptr-static void yy_flex_strncpy (char* s1, const char * s2, int n )-{-- int i;- for ( i = 0; i < n; ++i )- s1[i] = s2[i];-}-#endif--#ifdef YY_NEED_STRLEN-static int yy_flex_strlen (const char * s )-{- int n;- for ( n = 0; s[n]; ++n )- ;-- return n;-}-#endif--void *yyalloc (yy_size_t size )-{- return malloc(size);-}--void *yyrealloc (void * ptr, yy_size_t size )-{-- /* The cast to (char *) in the following accommodates both- * implementations that use char* generic pointers, and those- * that use void* generic pointers. It works with the latter- * because both ANSI C and C++ allow castless assignment from- * any pointer type to void*, and deal with argument conversions- * as though doing an assignment.- */- return realloc(ptr, size);-}--void yyfree (void * ptr )-{- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */-}--#define YYTABLES_NAME "yytables"--#line 37 "Nandlang.l"---void set_input_string(const char* in) {- yy_scan_string(in);-}--void end_lexical_scan(void) {- yy_delete_buffer(YY_CURRENT_BUFFER);-}
− benchmarks/NandlangBench/Main.hs
@@ -1,28 +0,0 @@-{-# LANGUAGE TemplateHaskell,- ScopedTypeVariables,- TypeFamilies,- UnboxedTuples,- TypeApplications #-}-module Main where-import Criterion.Main (Benchmark, bgroup, defaultMain)-import Control.DeepSeq (NFData)-import Data.ByteString (ByteString)---import Parsley.Internal.Verbose ()-import qualified NandlangBench.Parsley.Parser-import qualified NandlangBench.Bison.Parser-import qualified Parsley-import Shared.BenchmarkUtils--main :: IO ()-main = defaultMain [nandlang]--nandParsleyB :: ByteString -> Maybe ()-nandParsleyB = $$(Parsley.parse NandlangBench.Parsley.Parser.nandlang)--nandlang :: Benchmark-nandlang =- let nandTest :: NFData rep => (FilePath -> IO rep) -> String -> (rep -> Maybe ()) -> Benchmark- nandTest = benchmark ["benchmarks/inputs/fibonacci.nand", "benchmarks/inputs/fizzbuzz.nand", "benchmarks/inputs/arrays.nand"]- in bgroup "Nandlang"- [ nandTest bytestring "Parsley" nandParsleyB- , nandTest bytestring "Bison" NandlangBench.Bison.Parser.nand ]
− benchmarks/NandlangBench/Parsley/Functions.hs
@@ -1,19 +0,0 @@-module NandlangBench.Parsley.Functions where--import Data.Char (isAlpha, isAlphaNum)-import Data.Set (fromList, member)--nandIdentStart :: Char -> Bool-nandIdentStart c = isAlpha c || c == '_'--nandIdentLetter :: Char -> Bool-nandIdentLetter c = isAlphaNum c || c == '_'--nandUnreservedName :: String -> Bool-nandUnreservedName = \s -> not (member s keys)- where- keys = fromList ["if", "else", "while",- "function", "var"]--nandStringLetter :: Char -> Bool-nandStringLetter c = (c /= '"') && (c /= '\\') && (c > '\026')
− benchmarks/NandlangBench/Parsley/Parser.hs
@@ -1,104 +0,0 @@-{-# OPTIONS_GHC -fplugin=Parsley.OverloadedQuotesPlugin #-}-{-# LANGUAGE TemplateHaskellQuotes #-}-{-# LANGUAGE DeriveLift #-}-{-# LANGUAGE StandaloneDeriving #-}-module NandlangBench.Parsley.Parser where--import Prelude hiding (fmap, pure, (<*), (*>), (<*>), (<$>), (<$), pred)-import Parsley-import Parsley.Combinator (eof)-import Parsley.Char (token, oneOf)-import Parsley.Fold (skipMany, skipSome)---import Parsley.Garnish-import NandlangBench.Parsley.Functions-import Data.Char (isSpace)--nandlang :: Parser ()-nandlang = whitespace *> skipMany funcdef <* eof- where- index :: Parser ()- index = brackets nat- identifier :: Parser ()- identifier = try (identStart *> skipMany identLetter) *> whitespace- variable :: Parser ()- variable = identifier *> optional index-- literal :: Parser ()- literal = bit <|> charLit-- keyword :: String -> Parser ()- keyword s = try (string s *> notIdentLetter) *> whitespace-- identStart = satisfy [|nandIdentStart|]- identLetter = satisfy [|nandIdentLetter|]- notIdentLetter = notFollowedBy identLetter-- bit :: Parser ()- bit = (char '0' <|> char '1') *> whitespace-- nat :: Parser ()- nat = decimal-- charLit :: Parser ()- charLit = between (char '\'') (symbol '\'') charChar-- charChar :: Parser ()- charChar = void (satisfy [|nandStringLetter|]) <|> esc-- esc :: Parser ()- esc = char '\\' *> void (oneOf "0tnvfr")-- expr :: Parser ()- expr = nandexpr *> skipMany (symbol '!' *> nandexpr)-- nandexpr :: Parser ()- nandexpr = literal <|> funccallOrVar-- funccallOrVar :: Parser ()- funccallOrVar = identifier *> optional (parens exprlist <|> index)-- exprlist = commaSep expr- exprlist1 = commaSep1 expr- varlist = commaSep variable- varlist1 = commaSep1 variable-- funcparam = varlist *> optional (symbol ':' *> varlist)- varstmt = optional (keyword "var") *> varlist1 *> symbol '=' *> exprlist1 <* semi- ifstmt = keyword "if" *> expr *> block *> optional (keyword "else" *> block)- whilestmt = keyword "while" *> expr *> block- statement = ifstmt <|> whilestmt <|> try varstmt <|> expr <* semi- block = braces (skipMany statement)- funcdef = keyword "function" *> identifier *> parens funcparam *> block-- decimal :: Parser ()- decimal = number (oneOf ['0'..'9'])- hexadecimal = oneOf "xX" *> number (oneOf (['a'..'f'] ++ ['A'..'F'] ++ ['0'..'9']))- octal = oneOf "oO" *> number (oneOf ['0'..'7'])- number :: Parser a -> Parser ()- number digit = skipSome digit-- symbol :: Char -> Parser Char- symbol c = char c <* whitespace- parens :: Parser a -> Parser a- parens = between (symbol '(') (symbol ')')- brackets :: Parser a -> Parser a- brackets = between (symbol '[') (symbol ']')- braces :: Parser a -> Parser a- braces = between (symbol '{') (symbol '}')- semi :: Parser Char- semi = symbol ';'- comma :: Parser Char- comma = symbol ','- commaSep :: Parser a -> Parser ()- commaSep p = optional (commaSep1 p)- commaSep1 :: Parser a -> Parser ()- commaSep1 p = p *> skipMany (comma *> p)-- space :: Parser ()- space = void (satisfy [|isSpace|])- whitespace :: Parser ()- whitespace = skipMany (spaces <|> oneLineComment)- spaces :: Parser ()- spaces = skipSome space- oneLineComment :: Parser ()- oneLineComment = void (token "//" *> skipMany (satisfy [|(/= '\n')|]))
@@ -1,77 +0,0 @@-module Shared.Attoparsec.Extended (- module Data.Functor,- module Control.Applicative,- module Data.Attoparsec.Text,- module Control.Monad,- module Shared.Attoparsec.Extended- ) where--import Data.Attoparsec.Text hiding (match, string)-import Data.Functor (void, ($>))-import Control.Monad (MonadPlus)-import Control.Applicative (liftA2, liftA3, empty, Alternative, (<**>), (<|>), many)-import Data.List (foldl')--string = traverse char--token :: String -> Parser String-token = try . string--between o c p = o *> p <* c--oneOf = satisfy . inClass-noneOf = satisfy . notInClass--match :: (Monad m, Eq a) => [a] -> m a -> (a -> m b) -> m b -> m b-match xs p f def = p >>= (\x -> if elem x xs then f x else def)--skipSome :: Parser a -> Parser ()-skipSome p = void (some p)--some = many1--maybeP :: Parser a -> Parser (Maybe a)-maybeP p = option Nothing (Just <$> p)--fromMaybeP :: Monad m => m (Maybe a) -> m a -> m a-fromMaybeP mmx d = mmx >>= maybe d return--(<+>) :: Parser a -> Parser b -> Parser (Either a b)-p <+> q = Left <$> p <|> Right <$> q--(<:>) :: Parser a -> Parser [a] -> Parser [a]-(<:>) = liftA2 (:)--(<~>) :: Parser a -> Parser b -> Parser (a, b)-(<~>) = liftA2 (,)--pfoldl1 :: (b -> a -> b) -> b -> Parser a -> Parser b-pfoldl1 f k p = foldl' f k <$> some p--(>?>) :: MonadPlus m => m a -> (a -> Bool) -> m a-m >?> f = m >>= \x -> if f x then return x else empty--chainPre :: Parser (a -> a) -> Parser a -> Parser a-chainPre op p = flip (foldr ($)) <$> many op <*> p--chainPost :: Parser a -> Parser (a -> a) -> Parser a-chainPost p op = foldl' (flip ($)) <$> p <*> many op--chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a-chainl1 p op = chainPost p (flip <$> op <*> p)--chainr1 :: Parser a -> Parser (a -> a -> a) -> Parser a-chainr1 p op = let go = p <**> ((flip <$> op <*> go) <|> pure id) in go--data Level s a = InfixL [Parser (a -> a -> a)]- | InfixR [Parser (a -> a -> a)]- | Prefix [Parser (a -> a)]- | Postfix [Parser (a -> a)]--precedence :: [Level s a] -> Parser a -> Parser a-precedence levels atom = foldl' convert atom levels- where- convert x (InfixL ops) = chainl1 x (choice ops)- convert x (InfixR ops) = chainr1 x (choice ops)- convert x (Prefix ops) = chainPre (choice ops) x- convert x (Postfix ops) = chainPost x (choice ops)
@@ -1,40 +0,0 @@-{-# LANGUAGE TypeFamilies- , FlexibleContexts #-}-module Shared.BenchmarkUtils where--import Criterion.Main (Benchmark, bgroup, bench, nf, defaultMain, env)-import Control.DeepSeq (NFData)-import Control.Monad.Identity (Identity)-import Data.Text (Text)-import Data.ByteString (ByteString)-import qualified Text.Parsec as Parsec-import qualified Text.Megaparsec as Megaparsec-import qualified Data.Attoparsec.Text as Attoparsec-import qualified Data.Text.IO-import qualified Data.ByteString-import qualified Data.ByteString.Lazy-import qualified Shared.Parsec.Extended-import qualified Shared.Megaparsec.Extended--parsecParse :: Parsec.Stream s Identity Char => Shared.Parsec.Extended.Parser s a -> s -> Maybe a-parsecParse p = either (const Nothing) Just . Parsec.parse p ""--megaParse :: (Megaparsec.Stream s, Megaparsec.Token s ~ Char) => Shared.Megaparsec.Extended.Parser s a -> s -> Maybe a-megaParse = Megaparsec.parseMaybe--attoParse :: Attoparsec.Parser a -> Text -> Maybe a-attoParse p = Attoparsec.maybeResult . Attoparsec.parse p--string :: FilePath -> IO String-string = readFile-text :: FilePath -> IO Text-text = Data.Text.IO.readFile-bytestring :: FilePath -> IO ByteString-bytestring = Data.ByteString.readFile-lazy_bytestring :: FilePath -> IO Data.ByteString.Lazy.ByteString-lazy_bytestring = Data.ByteString.Lazy.readFile--benchmark :: (NFData a, NFData rep) => [FilePath] -> (FilePath -> IO rep) -> String -> (rep -> Maybe a) -> Benchmark-benchmark filenames load lib parser = env (traverse load filenames) (bgroup lib . (tasks filenames))- where- tasks filenames inputs = foldr (\f ts n -> bench f (nf parser (inputs !! n)) : ts (n+1)) (const []) filenames 0
@@ -1,73 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-module Shared.Megaparsec.Extended (- module Text.Megaparsec,- module Text.Megaparsec.Char,- module Control.Monad,- module Control.Applicative,- module Shared.Megaparsec.Extended- ) where-import Text.Megaparsec hiding (token, match)-import Text.Megaparsec.Char hiding (string)-import Data.List (foldl')-import Control.Monad (MonadPlus, void)-import Control.Applicative (liftA2, liftA3, empty, Alternative, (<**>))--type Parser s a = Parsec () s a--string :: (Stream s, Token s ~ Char) => String -> Parser s String-string = traverse char--token :: (Stream s, Token s ~ Char) => String -> Parser s String-token = try . string--($>) :: Functor f => f a -> b -> f b-($>) = flip (<$)--match :: (Monad m, Eq a) => [a] -> m a -> (a -> m b) -> m b -> m b-match xs p f def = p >>= (\x -> if elem x xs then f x else def)--maybeP :: (Stream s, Token s ~ Char) => Parser s a -> Parser s (Maybe a)-maybeP p = option Nothing (Just <$> p)--fromMaybeP :: Monad m => m (Maybe a) -> m a -> m a-fromMaybeP mmx d = mmx >>= maybe d return--(<+>) :: (Stream s, Token s ~ Char) => Parser s a -> Parser s b -> Parser s (Either a b)-p <+> q = Left <$> p <|> Right <$> q--(<:>) :: (Stream s, Token s ~ Char) => Parser s a -> Parser s [a] -> Parser s [a]-(<:>) = liftA2 (:)--(<~>) :: (Stream s, Token s ~ Char) => Parser s a -> Parser s b -> Parser s (a, b)-(<~>) = liftA2 (,)--pfoldl1 :: (Stream s, Token s ~ Char) => (b -> a -> b) -> b -> Parser s a -> Parser s b-pfoldl1 f k p = foldl' f k <$> some p--(>?>) :: MonadPlus m => m a -> (a -> Bool) -> m a-m >?> f = m >>= \x -> if f x then return x else empty--chainPre :: (Stream s, Token s ~ Char) => Parser s (a -> a) -> Parser s a -> Parser s a-chainPre op p = flip (foldr ($)) <$> many op <*> p--chainPost :: (Stream s, Token s ~ Char) => Parser s a -> Parser s (a -> a) -> Parser s a-chainPost p op = foldl' (flip ($)) <$> p <*> many op--chainl1 :: (Stream s, Token s ~ Char) => Parser s a -> Parser s (a -> a -> a) -> Parser s a-chainl1 p op = chainPost p (flip <$> op <*> p)--chainr1 :: (Stream s, Token s ~ Char) => Parser s a -> Parser s (a -> a -> a) -> Parser s a-chainr1 p op = let go = p <**> ((flip <$> op <*> go) <|> pure id) in go--data Level s a = InfixL [Parser s (a -> a -> a)]- | InfixR [Parser s (a -> a -> a)]- | Prefix [Parser s (a -> a)]- | Postfix [Parser s (a -> a)]--precedence :: (Stream s, Token s ~ Char) => [Level s a] -> Parser s a -> Parser s a-precedence levels atom = foldl' convert atom levels- where- convert x (InfixL ops) = chainl1 x (choice ops)- convert x (InfixR ops) = chainr1 x (choice ops)- convert x (Prefix ops) = chainPre (choice ops) x- convert x (Postfix ops) = chainPost x (choice ops)
@@ -1,70 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-module Shared.Parsec.Extended (- module Text.Parsec,- module Data.Functor,- module Control.Monad,- module Control.Monad.Identity,- module Control.Applicative,- module Shared.Parsec.Extended- ) where--import Text.Parsec hiding (token)-import Data.Functor (void, ($>))-import Control.Monad.Identity (Identity)-import Control.Monad (MonadPlus)-import Control.Applicative (liftA2, liftA3, empty, Alternative, (<**>))-import Data.List (foldl')--type Parser s a = Parsec s () a--token :: Stream s Identity Char => String -> Parser s String-token = try . string--match :: (Monad m, Eq a) => [a] -> m a -> (a -> m b) -> m b -> m b-match xs p f def = p >>= (\x -> if elem x xs then f x else def)--skipSome :: Stream s Identity Char => Parser s a -> Parser s ()-skipSome p = void (some p)--maybeP :: Stream s Identity Char => Parser s a -> Parser s (Maybe a)-maybeP p = option Nothing (Just <$> p)--fromMaybeP :: Monad m => m (Maybe a) -> m a -> m a-fromMaybeP mmx d = mmx >>= maybe d return--(<+>) :: Stream s Identity Char => Parser s a -> Parser s b -> Parser s (Either a b)-p <+> q = Left <$> p <|> Right <$> q--(<:>) :: Stream s Identity Char => Parser s a -> Parser s [a] -> Parser s [a]-(<:>) = liftA2 (:)--(<~>) :: Stream s Identity Char => Parser s a -> Parser s b -> Parser s (a, b)-(<~>) = liftA2 (,)--some :: Stream s Identity Char => Parser s a -> Parser s [a]-some = many1--pfoldl1 :: Stream s Identity Char => (b -> a -> b) -> b -> Parser s a -> Parser s b-pfoldl1 f k p = foldl' f k <$> some p--(>?>) :: MonadPlus m => m a -> (a -> Bool) -> m a-m >?> f = m >>= \x -> if f x then return x else empty--chainPre :: Stream s Identity Char => Parser s (a -> a) -> Parser s a -> Parser s a-chainPre op p = flip (foldr ($)) <$> many op <*> p--chainPost :: Stream s Identity Char => Parser s a -> Parser s (a -> a) -> Parser s a-chainPost p op = foldl' (flip ($)) <$> p <*> many op--data Level s a = InfixL [Parser s (a -> a -> a)]- | InfixR [Parser s (a -> a -> a)]- | Prefix [Parser s (a -> a)]- | Postfix [Parser s (a -> a)]--precedence :: Stream s Identity Char => [Level s a] -> Parser s a -> Parser s a-precedence levels atom = foldl' convert atom levels- where- convert x (InfixL ops) = chainl1 x (choice ops)- convert x (InfixR ops) = chainr1 x (choice ops)- convert x (Prefix ops) = chainPre (choice ops) x- convert x (Postfix ops) = chainPost x (choice ops)
parsley.cabal view
@@ -5,7 +5,7 @@ -- | +------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 2.0.0.0+version: 2.0.0.1 synopsis: A fast parser combinator library backed by Typed Template Haskell description: Parsley is a staged selective parser combinator library, which means it does not support monadic operations, and relies on Typed Template@@ -61,11 +61,11 @@ NoStarIsType --- ghc >= 8.6 && < 9.2,- build-depends: base >= 4.10 && < 4.16,+-- ghc >= 8.6 && < 9.8,+ build-depends: base >= 4.10 && < 4.19, parsley-core >= 2 && < 3, template-haskell >= 2.14 && < 3,- text >= 1.2.3 && < 1.3+ text >= 1.2.3 && < 2.1 hs-source-dirs: src/ghc default-language: Haskell2010@@ -86,6 +86,9 @@ ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module -Wno-unused-packages+ if impl(ghc >= 9.2)+ ghc-options: -Wno-missing-kind-signatures+ -Wno-implicit-lift source-repository head type: git@@ -95,24 +98,28 @@ build-depends: base >=4.10 && <5, parsley, parsley-core,- parsley-garnish, tasty, template-haskell+ build-tool-depends: cpphs:cpphs >= 1.18.8 && < 1.21 other-extensions: TemplateHaskellQuotes, TemplateHaskell hs-source-dirs: test default-language: Haskell2010- ghc-options: -fplugin=Parsley.OverloadedQuotesPlugin+ ghc-options: -pgmP cpphs -optP --cpp other-modules: TestUtils+ if false && impl(ghc < 9)+ build-depends: dump-core+ ghc-options: -fplugin=DumpCore test-suite parsley-test import: test-common type: exitcode-stdio-1.0- build-depends: tasty-hunit, tasty-quickcheck, th-test-utils, deepseq+ build-depends: tasty-hunit, tasty-quickcheck, th-test-utils, deepseq, containers main-is: Parsley/Tests.hs other-modules: Parsley.Alternative.Test, Parsley.Applicative.Test, Parsley.Combinator.Test, Parsley.Fold.Test, Parsley.Precedence.Test, Parsley.Register.Test, Parsley.Selective.Test, Parsley.Char.Test, Parsley.Alternative.Parsers, Parsley.Applicative.Parsers, Parsley.Combinator.Parsers, Parsley.Fold.Parsers, Parsley.Precedence.Parsers, Parsley.Register.Parsers, Parsley.Selective.Parsers, Parsley.Char.Parsers+ --Parsley.Javascript.Parsers, Parsley.Javascript.Shared, Parsley.Javascript.Test test-suite regression-test import: test-common@@ -125,8 +132,7 @@ build-tool-depends: happy:happy build-depends: base >=4.10 && <5, parsley,- parsley-garnish,- criterion >=1.5 && <1.6,+ gauge, deepseq, template-haskell, parsec,@@ -137,33 +143,34 @@ mtl, array, containers+ build-tool-depends: cpphs:cpphs >= 1.18.8 && < 1.21 hs-source-dirs: benchmarks other-extensions: TemplateHaskellQuotes, TemplateHaskell other-modules: Shared.BenchmarkUtils, Shared.Attoparsec.Extended, Shared.Megaparsec.Extended, Shared.Parsec.Extended default-language: Haskell2010- ghc-options: -rtsopts+ ghc-options: -rtsopts -pgmP cpphs -optP --cpp -ddump-splices -ddump-to-file if false && impl(ghc < 9) build-depends: dump-core ghc-options: -fplugin=DumpCore -benchmark brainfuck-bench- import: benchmark-common- type: exitcode-stdio-1.0- other-modules: BrainfuckBench.Shared, BrainfuckBench.Parsley.Parser, BrainfuckBench.Parsec.Parser, BrainfuckBench.Megaparsec.Parser,- BrainfuckBench.Attoparsec.Parser, BrainfuckBench.Handrolled.Parser, BrainfuckBench.Happy.Parser- main-is: BrainfuckBench/Main.hs+--benchmark brainfuck-bench+-- import: benchmark-common+-- type: exitcode-stdio-1.0+-- other-modules: BrainfuckBench.Shared, BrainfuckBench.Parsley.Parser, BrainfuckBench.Parsec.Parser, BrainfuckBench.Megaparsec.Parser,+-- BrainfuckBench.Attoparsec.Parser, BrainfuckBench.Handrolled.Parser, BrainfuckBench.Happy.Parser+-- main-is: BrainfuckBench/Main.hs -benchmark javascript-bench- import: benchmark-common- type: exitcode-stdio-1.0- other-modules: JavascriptBench.Shared, JavascriptBench.Parsley.Parser, JavascriptBench.Parsec.Parser, JavascriptBench.Megaparsec.Parser,- JavascriptBench.Attoparsec.Parser, JavascriptBench.Happy.Parser- main-is: JavascriptBench/Main.hs+--benchmark javascript-bench+-- import: benchmark-common+-- type: exitcode-stdio-1.0+-- other-modules: JavascriptBench.Shared, JavascriptBench.Parsley.Parser, JavascriptBench.Parsec.Parser, JavascriptBench.Megaparsec.Parser,+-- JavascriptBench.Attoparsec.Parser, JavascriptBench.Happy.Parser+-- main-is: JavascriptBench/Main.hs -benchmark nandlang-bench- import: benchmark-common- type: exitcode-stdio-1.0+--benchmark nandlang-bench+-- import: benchmark-common+-- type: exitcode-stdio-1.0 --cc-options: -O3- other-modules: NandlangBench.Parsley.Parser, NandlangBench.Parsley.Functions, NandlangBench.Bison.Parser- c-sources: benchmarks/NandlangBench/Bison/lex.yy.c, benchmarks/NandlangBench/Bison/Nandlang.tab.c- main-is: NandlangBench/Main.hs+-- other-modules: NandlangBench.Parsley.Parser, NandlangBench.Parsley.Functions, NandlangBench.Bison.Parser+-- c-sources: benchmarks/NandlangBench/Bison/lex.yy.c, benchmarks/NandlangBench/Bison/Nandlang.tab.c+-- main-is: NandlangBench/Main.hs
src/ghc/Parsley.hs view
@@ -29,7 +29,6 @@ import Prelude hiding (readFile) import Data.Text.IO (readFile)-import Parsley.InputExtras (Text16(..)) import Parsley.Internal (Input, Trace(trace)) import Parsley.Alternative as Alternative@@ -77,7 +76,7 @@ {-| This function generates a function that reads input from a file-and parses it. The input files contents are treated as `Text16`.+and parses it. The input files contents are treated as `Text`. See `parse` for more information. @@ -86,7 +85,7 @@ parseFromFile :: Trace => Parser a -- ^ The parser to be compiled -> Code (FilePath -> IO (Maybe a)) -- ^ The generated parsing function-parseFromFile p = [||\filename -> do input <- readFile filename; return ($$(parse p) (Text16 input))||]+parseFromFile p = [||\filename -> do input <- readFile filename; return ($$(parse p) input)||] {-| The default instance for `Trace`, which disables all debugging output about the parser compilation
src/ghc/Parsley/Alternative.hs view
src/ghc/Parsley/Applicative.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE PatternSynonyms, CPP #-} {-| Module : Parsley.Applicative Description : The @Applicative@ combinators@@ -23,7 +23,11 @@ (>>) ) where -import Prelude hiding (pure, (<*>), (*>), (<*), (>>), (<$>), fmap, (<$), traverse, sequence, repeat)+import Prelude hiding (pure, (<*>), (*>), (<*), (>>), (<$>), fmap, (<$), traverse, sequence, repeat+#if __GLASGOW_HASKELL__ >= 906+ , liftA2+#endif+ ) import Parsley.Defunctionalized (Defunc(CONS, CONST, ID, EMPTY), pattern FLIP_H, pattern UNIT) import Parsley.Internal (makeQ, Parser) import Parsley.ParserOps (ParserOps, pure)
src/ghc/Parsley/Char.hs view
src/ghc/Parsley/Combinator.hs view
src/ghc/Parsley/Debug.hs view
src/ghc/Parsley/Defunctionalized.hs view
src/ghc/Parsley/Fold.hs view
@@ -24,10 +24,10 @@ import Prelude hiding (pure, (<*>), (<$>), (*>), (<*)) import Parsley.Alternative ((<|>), option) import Parsley.Applicative (pure, (<*>), (<$>), (*>), (<*), (<:>), (<**>), void)-import Parsley.Defunctionalized (Defunc(FLIP, ID, COMPOSE, EMPTY, CONS, CONST, APP_H), pattern FLIP_H, pattern UNIT)+import Parsley.Defunctionalized (Defunc(FLIP, ID, COMPOSE, EMPTY, CONS, CONST), pattern FLIP_H, pattern UNIT) import Parsley.Internal (Parser) import Parsley.ParserOps (ParserOps)-import Parsley.Register (get, modify, newRegister, newRegister_)+import Parsley.Register (get, modify, newRegister) import qualified Parsley.Internal as Internal (loop) @@ -49,11 +49,7 @@ @since 2.0.0.0 -} prefix :: Parser (a -> a) -> Parser a -> Parser a-prefix op p =- newRegister_ ID (\r ->- loop (modify r (FLIP_H COMPOSE <$> op))- (get r))- <*> p+prefix op p = postfix (pure ID) (FLIP_H COMPOSE <$> op) <*> p {-| This combinator parses repeated applications of an operator to a single initial operand. This is@@ -271,6 +267,5 @@ -} sepEndBy1 :: Parser a -> Parser b -> Parser [a] sepEndBy1 p sep =- let seb1 = p <**> (sep *> (FLIP_H CONS <$> option EMPTY seb1)- <|> pure (APP_H (FLIP_H CONS) EMPTY))+ let seb1 = p <:> option EMPTY (sep *> option EMPTY seb1) in seb1
src/ghc/Parsley/InputExtras.hs view
@@ -1,3 +1,4 @@+{-# OPTIONS_GHC -Wno-deprecations #-} --FIXME: remove when Text16 is removed {-| Module : Parsley.InputExtras Description : Extra datatypes that can be used to wrap input
src/ghc/Parsley/ParserOps.hs view
@@ -60,7 +60,7 @@ @since 0.1.0.0 -}-instance ParserOps WQ where+instance {-# INCOHERENT #-} x ~ WQ => ParserOps x where pure = pure . BLACK satisfy = satisfy . BLACK conditional = conditional . map (first BLACK)@@ -71,7 +71,7 @@ @since 0.1.0.0 -}-instance {-# INCOHERENT #-} x ~ Defunc => ParserOps x where+instance ParserOps Defunc where pure = Internal.pure satisfy = Internal.satisfy conditional = Internal.conditional
src/ghc/Parsley/Precedence.hs view
@@ -155,7 +155,7 @@ @since 2.0.0.0 -}-instance GOps WQ where+instance {-# INCOHERENT #-} x ~ WQ => GOps x where gops fixity ps = gops fixity ps . BLACK {-|@@ -164,7 +164,7 @@ @since 2.0.0.0 -}-instance {-# INCOHERENT #-} x ~ Defunc => GOps x where+instance GOps Defunc where gops fixity ps = Op fixity (choice ps) {-|
src/ghc/Parsley/Register.hs view
src/ghc/Parsley/Selective.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-| Module : Parsley.Selective Description : The @Selective@ combinators@@ -22,7 +23,11 @@ fromMaybeP ) where -import Prelude hiding (pure, (<$>))+import Prelude hiding (pure, (<$>)+#if __GLASGOW_HASKELL__ >= 906+ , liftA2+#endif+ ) import Data.Function (fix) import Language.Haskell.TH.Syntax (Lift(..)) import Parsley.Alternative (empty)@@ -133,6 +138,7 @@ @since 0.1.0.0 -}+--TODO: This /could/ be improved by generating a neat switch for Characters, and forwarding the input. match :: (Eq a, Lift a) => [a] -- ^ The domain of the function given as the third argument -> Parser a -- ^ The parser whose result will be given to the function
test/Parsley/Alternative/Parsers.hs view
test/Parsley/Alternative/Test.hs view
test/Parsley/Applicative/Parsers.hs view
test/Parsley/Applicative/Test.hs view
test/Parsley/Char/Parsers.hs view
test/Parsley/Char/Test.hs view
test/Parsley/Combinator/Parsers.hs view
@@ -1,1 +1,20 @@ module Parsley.Combinator.Parsers where++import Prelude hiding ((*>), (<*))++import Parsley+import Parsley.Combinator+import Parsley.Char++factoring :: Parser [String]+factoring = many $ (more *>) $+ string "if" <* notFollowedBy (oneOf ['a'..'z'])+ <|> string "while" <* notFollowedBy (oneOf ['a'..'z'])+ <|> string "return" <* notFollowedBy (oneOf ['a'..'z'])+ <|> string "continue" <* notFollowedBy (oneOf ['a'..'z'])+ <|> string "break" <* notFollowedBy (oneOf ['a'..'z'])+ <|> string "for" <* notFollowedBy (oneOf ['a'..'z'])+ <|> q+ <|> q+ where+ q = string "hello!" <* notFollowedBy (oneOf ['a'..'z'])
test/Parsley/Combinator/Test.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, UnboxedTuples, ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell, UnboxedTuples, ScopedTypeVariables, TypeApplications #-} module Parsley.Combinator.Test where import Test.Tasty import Test.Tasty.HUnit@@ -14,6 +14,7 @@ tests = testGroup "Combinator" [ eofTests , moreTests , someTillTests+ , factoringTests ] isNull :: String -> Maybe ()@@ -40,3 +41,16 @@ someTillTests :: TestTree someTillTests = testGroup "someTill should" []++factoring :: String -> Maybe [String]+factoring = $$(runParserMocked Parsers.factoring [||Parsers.factoring||])++factoringTests :: TestTree+factoringTests = testGroup "factoring should"+ [ testCase "succeed on input" $ factoring "" @?= Just []+ , testCase "succeed on input" $ factoring "if" @?= Just ["if"]+ , testCase "succeed on input" $ factoring "continue" @?= Just ["continue"]+ , testCase "succeed on input" $ factoring "hello!" @?= Just ["hello!"]+ , testCase "succeed on input" $ factoring "while." @?= Just ["while"]+ , testCase "succeed on input" $ factoring "coodbye" @?= Nothing+ ]
test/Parsley/Fold/Parsers.hs view
@@ -1,25 +1,29 @@-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE CPP, TemplateHaskell #-}+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}+{-# HLINT ignore "Redundant bracket" #-} module Parsley.Fold.Parsers where import Prelude hiding (pure, (<*>), (*>), (<*)) import Parsley import Parsley.Fold---import Parsley.Garnish+import Parsley.Defunctionalized +#define QQ(x) (makeQ (x) [|| x ||])+ plusOne :: Parser Int-plusOne = prefix (string "++" $> [|succ|]) (char '1' $> [|1|])+plusOne = prefix (string "++" $> QQ(succ)) (char '1' $> LIFTED 1) plusOne' :: Parser Int-plusOne' = prefix (try (string "++") $> [|succ|]) (char '1' $> [|1|])+plusOne' = prefix (try (string "++") $> QQ(succ)) (char '1' $> LIFTED 1) plusOnePure :: Parser Int-plusOnePure = try (prefix (string "++" $> [|succ|]) (pure [|1|])) <|> pure [|0|]+plusOnePure = try (prefix (string "++" $> QQ(succ)) (pure (LIFTED 1))) <|> pure (LIFTED 0) onePlus :: Parser Int-onePlus = postfix (char '1' $> [|1|]) (string "++" $> [|succ|])+onePlus = postfix (char '1' $> LIFTED 1) (string "++" $> QQ(succ)) onePlus' :: Parser Int-onePlus' = postfix (char '1' $> [|1|]) (try (string "++") $> [|succ|])+onePlus' = postfix (char '1' $> LIFTED 1) (try (string "++") $> QQ(succ)) manyAA :: Parser [String] manyAA = many (string "aa")
test/Parsley/Fold/Test.hs view
@@ -39,7 +39,7 @@ plusOne "1" @?= Just 1 plusOne "" @?= Nothing plusOnePure "" @?= Just 1- , testCase "parser all operators that precede" $ do+ , testCase "parse all operators that precede" $ do plusOne "++++1" @?= Just 3 plusOne' "++++1" @?= Just 3 plusOnePure "+" @?= Just 0
test/Parsley/Precedence/Parsers.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE TemplateHaskellQuotes, MultiParamTypeClasses #-}+{-# LANGUAGE CPP, TemplateHaskellQuotes, MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}+{-# HLINT ignore "Redundant bracket" #-} module Parsley.Precedence.Parsers where import Prelude hiding (pure, (<*>), (*>), (<*), (<$>), ($>), pred)@@ -7,17 +9,20 @@ import Parsley.Fold (somel) import Parsley.Char (oneOf) import Data.Char (digitToInt)+import Parsley.Defunctionalized +#define QQ(x) (makeQ (x) [|| x ||])+ data Expr = Add Expr Expr | Mul Expr Expr | Negate Expr | Num Int deriving (Eq, Show) number :: Parser Int-number = somel [| \x d -> x * 10 + digitToInt d |] [|0|] (oneOf ['0'..'9'])+number = somel QQ(\x d -> x * 10 + digitToInt d) (LIFTED 0) (oneOf ['0'..'9']) expr :: Parser Expr-expr = precHomo ([|Num|] <$> number)- [ ops Prefix [string "negate" $> [|Negate|]]- , ops InfixL [char '*' $> [|Mul|]]- , ops InfixR [char '+' $> [|Add|]]+expr = precHomo (QQ(Num) <$> number)+ [ ops Prefix [string "negate" $> QQ(Negate)]+ , ops InfixL [char '*' $> QQ(Mul)]+ , ops InfixR [char '+' $> QQ(Add)] ] data Pred = Or Term Pred | OfTerm Term deriving (Eq, Show)@@ -36,7 +41,7 @@ downcast _ = Nothing pred = precedence $- gops InfixR [char '|' $> [|Or|]] [|OfTerm|] +<- sops InfixR [char '&' $> [|And|]] +<- sops Prefix [char '!' $> [|Not|]] +<- Atom (char 'T' $> [|T|] <|> char 'F' $> [|F|] <|> char '(' *> ([|Parens|] <$> pred) <* char ')')+ gops InfixR [char '|' $> QQ(Or)] QQ(OfTerm) +<+ sops InfixR [char '&' $> QQ(And)] +<+ sops Prefix [char '!' $> QQ(Not)] +<+ Atom (char 'T' $> QQ(T) <|> char 'F' $> QQ(F) <|> char '(' *> (QQ(Parens) <$> pred) <* char ')')
test/Parsley/Precedence/Test.hs view
test/Parsley/Register/Parsers.hs view
@@ -5,28 +5,28 @@ import Data.Char (isDigit) import Parsley (Parser, item, char, (*>), (<*), (<|>)) import Parsley.Register---import Parsley.Garnish+import Parsley.Defunctionalized getPure :: Parser Int-getPure = newRegister_ [|8|] get+getPure = newRegister_ (LIFTED 8) get getPersists :: Parser Int-getPersists = newRegister_ [|8|] (\r -> item *> get r)+getPersists = newRegister_ (LIFTED 8) (\r -> item *> get r) getPersistsBranch :: Parser Int-getPersistsBranch = newRegister_ [|8|] (\r -> (char 'a' *> get r) <|> get r)+getPersistsBranch = newRegister_ (LIFTED 8) (\r -> (char 'a' *> get r) <|> get r) getNoInput :: Parser Int-getNoInput = newRegister_ [|8|] (\r -> get r <* item)+getNoInput = newRegister_ (LIFTED 8) (\r -> get r <* item) putPure :: Parser Int-putPure = newRegister_ [|8|] (\r -> put_ r [|7|] *> get r)+putPure = newRegister_ (LIFTED 8) (\r -> put_ r (LIFTED 7) *> get r) putSeq :: Parser Char-putSeq = newRegister_ [|'a'|] (\r -> put r item *> get r)+putSeq = newRegister_ (LIFTED 'a') (\r -> put r item *> get r) putPut :: Parser Int-putPut = newRegister_ [|7|] (\r -> put_ r [|5|] *> put_ r [|6|] *> get r)+putPut = newRegister_ (LIFTED 7) (\r -> put_ r (LIFTED 5) *> put_ r (LIFTED 6) *> get r) putCarries :: Parser Bool-putCarries = newRegister_ [|False|] (\r -> (put_ r [|True|] *> item *> put_ r [|False|] *> get r) <|> get r)+putCarries = newRegister_ (LIFTED False) (\r -> (put_ r (LIFTED True) *> item *> put_ r (LIFTED False) *> get r) <|> get r)
test/Parsley/Register/Test.hs view
test/Parsley/Selective/Parsers.hs view
test/Parsley/Selective/Test.hs view
test/Parsley/Tests.hs view
@@ -7,6 +7,7 @@ import qualified Parsley.Precedence.Test as Precedence import qualified Parsley.Register.Test as Register import qualified Parsley.Selective.Test as Selective+--import qualified Parsley.Javascript.Test as Javascript main :: IO () main = defaultMain tests@@ -19,4 +20,5 @@ , Precedence.tests , Register.tests , Selective.tests+ --, Javascript.tests ]
test/Regression/Parsers.hs view
@@ -5,10 +5,26 @@ import Data.Char (isDigit) import Parsley import Parsley.Char (token)---import Parsley.Garnish+import Parsley.Register (newRegister_, put_, get)+import Parsley.Defunctionalized (Defunc(LIFTED))+import Parsley.Internal.Core.Primitives (loop) issue26_ex1 :: Parser () issue26_ex1 = (token "123" <|> token "") *> void (token "abc") issue26_ex2 :: Parser () issue26_ex2 = (token "123" <|> token "45") *> void (token "abc")++issue41_ex1 :: Parser Bool+issue41_ex1 = newRegister_ (LIFTED False) $ \reg -> optional (try (char 'a' *> put_ reg (LIFTED True) *> char 'b')) *> get reg++issue41_ex2 :: Parser Bool+issue41_ex2 = newRegister_ (LIFTED False) $ \reg -> try ((string "abc" *> get reg) <|> (put_ reg (LIFTED True) *> get reg)) <|> get reg++issue41_ex3 :: Parser Bool+issue41_ex3 = newRegister_ (LIFTED False) $ \reg -> try ((string "abc" *> get reg) <|> (put_ reg (LIFTED True) *> item *> get reg)) <|> get reg++badFactor :: Parser String+badFactor = string "a"+ <|> string "uxy" *> loop (void (char 'a')) unit *> string "z"+ <|> string "b"
test/Regression/Tests.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TemplateHaskell, UnboxedTuples, ScopedTypeVariables, TypeApplications #-}+{-# OPTIONS_GHC -ddump-splices -ddump-to-file #-} module Main where import Test.Tasty import Test.Tasty.HUnit@@ -8,20 +9,56 @@ import Parsley (parse) import Parsley.InputExtras (CharList(..)) +import Parsley.Internal.Verbose ()+ main :: IO () main = defaultMain tests tests :: TestTree-tests = testGroup "Regression Tests" [ issue26 ]+tests = testGroup "Regression Tests" [ issue26, issue41, badFactorTests ] issue26 :: TestTree issue26 = testGroup "#26 Coin draining on bindings is wrong"- [ testCase "" $ issue26_ex1 (CharList "123ab") @?= Nothing- , testCase "" $ issue26_ex2 (CharList "123ab") @?= Nothing+ [ testCase "" $ issue26_ex1 "123ab" @?= Nothing+ , testCase "" $ issue26_ex2 "123ab" @?= Nothing ] -issue26_ex1 :: CharList -> Maybe ()+issue41 :: TestTree+issue41 = testGroup "#41 Length-factoring can cross `put` but shouldn't"+ [ testCase "it should work when enough input is given" $ issue41_ex1 "ab" @?= Just True+ , testCase "it should work when enough input is given" $ issue41_ex1 "ac" @?= Just True+ , testCase "it should prevent factoring" $ issue41_ex1 "a" @?= Just True+ , testCase "it should prevent factoring" $ issue41_ex2 "a" @?= Just False+ , testCase "it should prevent factoring" $ issue41_ex2 "b" @?= Just True+ , testCase "it should prevent factoring" $ issue41_ex2 "ab" @?= Just False+ , testCase "it should prevent factoring" $ issue41_ex2 "abc" @?= Just False+ , testCase "it should prevent factoring" $ issue41_ex3 "a" @?= Just False+ , testCase "it should prevent factoring" $ issue41_ex3 "b" @?= Just True+ , testCase "it should prevent factoring" $ issue41_ex3 "ab" @?= Just False+ , testCase "it should prevent factoring" $ issue41_ex3 "abc" @?= Just False+ ]++badFactorTests :: TestTree+badFactorTests = testGroup "bad factoring within loops"+ [ testCase "it should not die in loop" $ badFactor "uxyaz" @?= Just "z"+ , testCase "it should still work without a" $ badFactor "uxyz" @?= Just "z"+ , testCase "it should fail gracefully on x" $ badFactor "u" @?= Nothing+ ]++issue26_ex1 :: String -> Maybe () issue26_ex1 = $$(Parsley.parse Parsers.issue26_ex1) -issue26_ex2 :: CharList -> Maybe ()+issue26_ex2 :: String -> Maybe () issue26_ex2 = $$(Parsley.parse Parsers.issue26_ex2)++issue41_ex1 :: String -> Maybe Bool+issue41_ex1 = $$(Parsley.parse Parsers.issue41_ex1)++issue41_ex2 :: String -> Maybe Bool+issue41_ex2 = $$(Parsley.parse Parsers.issue41_ex2)++issue41_ex3 :: String -> Maybe Bool+issue41_ex3 = $$(Parsley.parse Parsers.issue41_ex3)++badFactor :: String -> Maybe String+badFactor = $$(Parsley.parse Parsers.badFactor)
test/TestUtils.hs view