Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate _qualified_ imports to avoid clashes with user code #259

Merged
merged 6 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/haskell-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#
# For more information, see https://github.com/andreasabel/haskell-ci
#
# version: 0.17.20240127
# version: 0.18.0.20240225
#
# REGENDATA ("0.17.20240127",["github","alex.cabal"])
# REGENDATA ("0.18.0.20240225",["github","alex.cabal"])
#
name: Haskell-CI
on:
Expand All @@ -32,9 +32,9 @@ jobs:
strategy:
matrix:
include:
- compiler: ghc-9.8.1
- compiler: ghc-9.8.2
compilerKind: ghc
compilerVersion: 9.8.1
compilerVersion: 9.8.2
setup-method: ghcup
allow-failure: false
- compiler: ghc-9.6.4
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## Changes in 3.5.1.0

* Drop generating output for GHC < 6.4.
* Use qualified imports in generated code (except for `Prelude`)
([Issue #258](https://github.com/haskell/alex/issues/258)).
* Suppress warnings `tabs` and `unused-imports` for generated code
([Issue #255](https://github.com/haskell/alex/issues/255)).
* Tested with GHC 8.0 - 9.8.2.

_Andreas Abel, 2024-02-29_

## Changes in 3.5.0.0

* Add option `--numeric-version`.
Expand Down
4 changes: 2 additions & 2 deletions alex.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: >= 1.10
name: alex
version: 3.5.0.0
version: 3.5.1.0
-- don't forget updating changelog.md!
license: BSD3
license-file: LICENSE
Expand All @@ -22,7 +22,7 @@ category: Development
build-type: Simple

tested-with:
GHC == 9.8.1
GHC == 9.8.2
GHC == 9.6.4
GHC == 9.4.8
GHC == 9.2.8
Expand Down
36 changes: 14 additions & 22 deletions data/AlexTemplate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
# define FAST_INT Int#
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
# if __GLASGOW_HASKELL__ > 706
# define GTE(n,m) (tagToEnum# (n >=# m))
# define EQ(n,m) (tagToEnum# (n ==# m))
# define GTE(n,m) (GHC.Exts.tagToEnum# (n >=# m))
# define EQ(n,m) (GHC.Exts.tagToEnum# (n ==# m))
# else
# define GTE(n,m) (n >=# m)
# define EQ(n,m) (n ==# m)
Expand All @@ -40,9 +40,6 @@
#ifdef ALEX_GHC
data AlexAddr = AlexA# Addr#
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
#if __GLASGOW_HASKELL__ < 503
uncheckedShiftL# = shiftL#
#endif

{-# INLINE alexIndexInt16OffAddr #-}
alexIndexInt16OffAddr :: AlexAddr -> Int# -> Int#
Expand All @@ -56,12 +53,12 @@ alexIndexInt16OffAddr (AlexA# arr) off =
off' = off *# 2#
#else
#if __GLASGOW_HASKELL__ >= 901
int16ToInt#
GHC.Exts.int16ToInt#
#endif
(indexInt16OffAddr# arr off)
#endif
#else
alexIndexInt16OffAddr arr off = arr ! off
alexIndexInt16OffAddr = (Data.Array.!)
#endif

#ifdef ALEX_GHC
Expand All @@ -81,24 +78,19 @@ alexIndexInt32OffAddr (AlexA# arr) off =
off' = off *# 4#
#else
#if __GLASGOW_HASKELL__ >= 901
int32ToInt#
GHC.Exts.int32ToInt#
#endif
(indexInt32OffAddr# arr off)
#endif
#else
alexIndexInt32OffAddr arr off = arr ! off
alexIndexInt32OffAddr = (Data.Array.!)
#endif

#ifdef ALEX_GHC

#if __GLASGOW_HASKELL__ < 503
quickIndex arr i = arr ! i
#else
-- GHC >= 503, unsafeAt is available from Data.Array.Base.
quickIndex = unsafeAt
#endif
#else
quickIndex arr i = arr ! i
quickIndex = (Data.Array.!)
#endif

-- -----------------------------------------------------------------------------
Expand All @@ -120,26 +112,26 @@ alexScanUser user__ input__ IBOX(sc)
case alexGetByte input__ of
Nothing ->
#ifdef ALEX_DEBUG
trace ("End of input.") $
Debug.Trace.trace ("End of input.") $
#endif
AlexEOF
Just _ ->
#ifdef ALEX_DEBUG
trace ("Error.") $
Debug.Trace.trace ("Error.") $
#endif
AlexError input__'

(AlexLastSkip input__'' len, _) ->
#ifdef ALEX_DEBUG
trace ("Skipping.") $
Debug.Trace.trace ("Skipping.") $
#endif
AlexSkip input__'' len

(AlexLastAcc k input__''' len, _) ->
#ifdef ALEX_DEBUG
trace ("Accept.") $
Debug.Trace.trace ("Accept.") $
#endif
AlexToken input__''' len (alex_actions ! k)
AlexToken input__''' len ((Data.Array.!) alex_actions k)


-- Push the input through the DFA, remembering the most recent accepting
Expand All @@ -155,7 +147,7 @@ alex_scan_tkn user__ orig_input len input__ s last_acc =
Nothing -> (new_acc, input__)
Just (c, new_input) ->
#ifdef ALEX_DEBUG
trace ("State: " ++ show IBOX(s) ++ ", char: " ++ show c ++ " " ++ (show . chr . fromIntegral) c) $
Debug.Trace.trace ("State: " ++ show IBOX(s) ++ ", char: " ++ show c ++ " " ++ (show . chr . fromIntegral) c) $
#endif
case fromIntegral c of { IBOX(ord_c) ->
let
Expand Down Expand Up @@ -226,7 +218,7 @@ alexPrevCharIs c _ input__ _ _ = c == alexInputPrevChar input__
alexPrevCharMatches f _ input__ _ _ = f (alexInputPrevChar input__)

--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _
alexPrevCharIsOneOf arr _ input__ _ _ = arr ! alexInputPrevChar input__
alexPrevCharIsOneOf arr _ input__ _ _ = arr Data.Array.! alexInputPrevChar input__

--alexRightContext :: Int -> AlexAccPred _
alexRightContext IBOX(sc) user__ _ _ input__ =
Expand Down
85 changes: 49 additions & 36 deletions src/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import Paths_alex ( version, getDataDir )
import Control.Exception ( bracketOnError )
import Control.Monad ( when, liftM )
import Data.Char ( chr )
import Data.List ( isSuffixOf, nub )
import Data.List ( intercalate, isSuffixOf, nub )
import Data.Map ( Map )
import Data.Version ( showVersion )
import System.Console.GetOpt ( getOpt, usageInfo, ArgOrder(..), OptDescr(..), ArgDescr(..) )
Expand Down Expand Up @@ -385,48 +385,61 @@ optNoWarnings =
]

importsToInject :: Target -> [CLIFlags] -> String
importsToInject _ cli = always_imports ++ debug_imports ++ glaexts_import
importsToInject _ cli = unlines $
always_imports ++ debug_imports ++ glaexts_import
where
glaexts_import | OptGhcTarget `elem` cli = import_glaexts
| otherwise = ""
| otherwise = []

debug_imports | OptDebugParser `elem` cli = import_debug
| otherwise = ""
| otherwise = []

-- CPP is turned on for -fglasogw-exts, so we can use conditional
-- compilation. We need to #include "config.h" to get hold of
-- We need to #include "ghcconfig.h" to get hold of
-- WORDS_BIGENDIAN (see AlexTemplate.hs).

always_imports :: String
always_imports = "#if __GLASGOW_HASKELL__ >= 603\n" ++
"#include \"ghcconfig.h\"\n" ++
"#elif defined(__GLASGOW_HASKELL__)\n" ++
"#include \"config.h\"\n" ++
"#endif\n" ++
"#if __GLASGOW_HASKELL__ >= 503\n" ++
"import Data.Array\n" ++
"#else\n" ++
"import Array\n" ++
"#endif\n"

import_glaexts :: String
import_glaexts = "#if __GLASGOW_HASKELL__ >= 503\n" ++
"import Data.Array.Base (unsafeAt)\n" ++
"import GHC.Exts\n" ++
"#else\n" ++
"import GlaExts\n" ++
"#endif\n"

import_debug :: String
import_debug = "#if __GLASGOW_HASKELL__ >= 503\n" ++
"import Data.Char (chr)\n" ++
"import System.IO\n" ++
"import System.IO.Unsafe\n" ++
"import Debug.Trace\n" ++
"#else\n" ++
"import IO\n" ++
"import IOExts\n" ++
"#endif\n"
always_imports :: [String]
always_imports =
[ "#include \"ghcconfig.h\""
, "import qualified Data.Array"
]

import_glaexts :: [String]
import_glaexts =
[ "import Data.Array.Base (unsafeAt)"
, "import GHC.Exts (" ++ imports ++ ")"
, "import qualified GHC.Exts"
]
where
-- We can import anything mentioning # safely,
-- assuming the user code does not make use of
-- MagicHash.
imports = intercalate ","
[ "Addr#"
, "Int#"
, "Int(I#)"
, "(*#)"
, "(+#)"
, "(-#)"
, "(==#)"
, "(>=#)"
, "indexCharOffAddr#"
, "indexInt16OffAddr#"
, "indexInt32OffAddr#"
, "int2Word#"
, "narrow16Int#"
, "narrow32Int#"
, "negateInt#"
, "or#"
, "ord#"
, "uncheckedShiftL#"
, "word2Int#"
]

import_debug :: [String]
import_debug =
[ "import Data.Char (chr)"
, "import qualified Debug.Trace"
]

templateDir :: IO FilePath -> [CLIFlags] -> IO FilePath
templateDir def cli
Expand Down
32 changes: 16 additions & 16 deletions src/Output.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ outputDFA target _ _ scheme dfa
. str " \"" . str (hex_chars ints) . str "\"#\n"

_ ->
str nm . str " :: Array Int Int\n"
str nm . str " :: Data.Array.Array Int Int\n"
. str nm . str " = "
. formatArray "listArray" upper_bound (map shows ints)
. formatArray "Data.Array.listArray" upper_bound (map shows ints)
. nl

outputAccept :: ShowS
Expand All @@ -84,7 +84,7 @@ outputDFA target _ _ scheme dfa
-- see: https://github.com/simonmar/alex/issues/98
-- str accept_nm . str " :: Array Int (AlexAcc " . str userStateTy . str ")\n"
str accept_nm . str " = "
. formatArray "listArray" n_states (snd (mapAccumR outputAccs 0 accept))
. formatArray "Data.Array.listArray" n_states (snd (mapAccumR outputAccs 0 accept))
. nl

gscanActionType res =
Expand All @@ -95,63 +95,63 @@ outputDFA target _ _ scheme dfa
where
(nacts, acts) = mapAccumR outputActs 0 accept
actionsArray :: ShowS
actionsArray = formatArray "array" nacts (concat acts)
actionsArray = formatArray "Data.Array.array" nacts (concat acts)
body :: ShowS
body = str actions_nm . str " = " . actionsArray . nl
signature :: ShowS
signature = case scheme of
Default { defaultTypeInfo = Just (Nothing, actionty) } ->
str actions_nm . str " :: Array Int (" . str actionty . str ")\n"
str actions_nm . str " :: Data.Array.Array Int (" . str actionty . str ")\n"
Default { defaultTypeInfo = Just (Just tyclasses, actionty) } ->
str actions_nm . str " :: (" . str tyclasses
. str ") => Array Int (" . str actionty . str ")\n"
. str ") => Data.Array.Array Int (" . str actionty . str ")\n"
GScan { gscanTypeInfo = Just (Nothing, toktype) } ->
str actions_nm . str " :: Array Int ("
str actions_nm . str " :: Data.Array.Array Int ("
. gscanActionType toktype . str ")\n"
GScan { gscanTypeInfo = Just (Just tyclasses, toktype) } ->
str actions_nm . str " :: (" . str tyclasses
. str ") => Array Int ("
. str ") => Data.Array.Array Int ("
. gscanActionType toktype . str ")\n"
Basic { basicStrType = strty,
basicTypeInfo = Just (Nothing, toktype) } ->
str actions_nm . str " :: Array Int ("
str actions_nm . str " :: Data.Array.Array Int ("
. str (show strty) . str " -> " . str toktype
. str ")\n"
Basic { basicStrType = strty,
basicTypeInfo = Just (Just tyclasses, toktype) } ->
str actions_nm . str " :: (" . str tyclasses
. str ") => Array Int ("
. str ") => Data.Array.Array Int ("
. str (show strty) . str " -> " . str toktype
. str ")\n"
Posn { posnStrType = strty,
posnTypeInfo = Just (Nothing, toktype) } ->
str actions_nm . str " :: Array Int (AlexPosn -> "
str actions_nm . str " :: Data.Array.Array Int (AlexPosn -> "
. str (show strty) . str " -> " . str toktype
. str ")\n"
Posn { posnStrType = strty,
posnTypeInfo = Just (Just tyclasses, toktype) } ->
str actions_nm . str " :: (" . str tyclasses
. str ") => Array Int (AlexPosn -> "
. str ") => Data.Array.Array Int (AlexPosn -> "
. str (show strty) . str " -> " . str toktype
. str ")\n"
Monad { monadStrType = strty,
monadTypeInfo = Just (Nothing, toktype) } ->
let
actintty = if strty == Lazy then "Int64" else "Int"
in
str actions_nm . str " :: Array Int (AlexInput -> "
str actions_nm . str " :: Data.Array.Array Int (AlexInput -> "
. str actintty . str " -> Alex(" . str toktype . str "))\n"
Monad { monadStrType = strty,
monadTypeInfo = Just (Just tyclasses, toktype) } ->
let
actintty = if strty == Lazy then "Int64" else "Int"
in
str actions_nm . str " :: (" . str tyclasses
. str ") => Array Int (AlexInput -> "
. str ") => Data.Array.Array Int (AlexInput -> "
. str actintty . str " -> Alex(" . str toktype . str "))\n"
_ ->
-- No type signature: we don't know what the type of the actions is.
-- str accept_nm . str " :: Array Int (Accept Code)\n"
-- str accept_nm . str " :: Data.Array.Array Int (Accept Code)\n"
id


Expand Down Expand Up @@ -323,7 +323,7 @@ outputDFA target _ _ scheme dfa
= str code

-- outputArr arr
-- = str "array " . shows (bounds arr) . space
-- = str "Data.Array.array " . shows (bounds arr) . space
-- . shows (assocs arr)

-- -----------------------------------------------------------------------------
Expand Down