{-
    BNF Converter: Java 1.5 Abstract Vistor generator
    Copyright (C) 2006 Bjorn Bringert
    Based on CFtoVisitSkel.hs, Copyright (C) 2004-2006  Michael Pellauer

-}

module BNFC.Backend.Java.CFtoAbstractVisitor (cf2AbstractVisitor) where

import BNFC.CF
import BNFC.Utils ((+++))
import BNFC.Backend.Common.NamedVariables

cf2AbstractVisitor :: String -> String -> CF -> String
cf2AbstractVisitor :: [Char] -> [Char] -> CF -> [Char]
cf2AbstractVisitor [Char]
packageBase [Char]
packageAbsyn CF
cf = [[Char]] -> [Char]
unlines
    [ [Char]
"package" [Char] -> [Char] -> [Char]
+++ [Char]
packageBase [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
";"
    , [Char]
""
    , [Char]
"/** Abstract Visitor */"
    , [Char]
""
    , [Char]
"public class AbstractVisitor<R,A> implements AllVisitor<R,A> {"
    , ((Cat, [Rule]) -> [Char]) -> [(Cat, [Rule])] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Char] -> [[Char]] -> (Cat, [Rule]) -> [Char]
prData [Char]
packageAbsyn [[Char]]
user) [(Cat, [Rule])]
groups
    , [Char]
"}"
    ]
  where
    user :: [[Char]]
user   = (([Char], Reg) -> [Char]) -> [([Char], Reg)] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char], Reg) -> [Char]
forall a b. (a, b) -> a
fst ([([Char], Reg)] -> [[Char]]) -> [([Char], Reg)] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ CF -> [([Char], Reg)]
forall f. CFG f -> [([Char], Reg)]
tokenPragmas CF
cf
    groups :: [(Cat, [Rule])]
groups = [ (Cat, [Rule])
g
      | g :: (Cat, [Rule])
g@(Cat
c,[Rule]
_) <- [(Cat, [Rule])] -> [(Cat, [Rule])]
fixCoercions (CF -> [(Cat, [Rule])]
ruleGroupsInternals CF
cf), Bool -> Bool
not (Cat -> Bool
isList Cat
c) ]

--Traverses a category based on its type.
prData :: String -> [UserDef] -> (Cat, [Rule]) -> String
prData :: [Char] -> [[Char]] -> (Cat, [Rule]) -> [Char]
prData [Char]
packageAbsyn [[Char]]
user (Cat
cat, [Rule]
rules) = [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ [[[Char]]] -> [[Char]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
  [ [ [Char]
"    /* " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat Cat
cat [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" */" ]
  , (Rule -> [[Char]]) -> [Rule] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Char] -> [[Char]] -> Cat -> Rule -> [[Char]]
prRule [Char]
packageAbsyn [[Char]]
user Cat
cat) [Rule]
rules
  , [ [Char]
"    public R visitDefault(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
packageAbsyn [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"." [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat Cat
cat [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" p, A arg) {"
    , [Char]
"      throw new IllegalArgumentException(this.getClass()" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".getName() + \": \" + p);"
    , [Char]
"    }"
    ]
  ]

--traverses a standard rule.
prRule :: String -> [UserDef] -> Cat -> Rule -> [String]
prRule :: [Char] -> [[Char]] -> Cat -> Rule -> [[Char]]
prRule [Char]
packageAbsyn [[Char]]
_ Cat
_ (Rule RFun
fun RCat
_ SentForm
_ InternalRule
_)
  | Bool -> Bool
not (RFun -> Bool
forall a. IsFun a => a -> Bool
isCoercion RFun
fun Bool -> Bool -> Bool
|| RFun -> Bool
forall a. IsFun a => a -> Bool
isDefinedRule RFun
fun) = [Char] -> [[Char]]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Char] -> [[Char]]) -> [Char] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
      [ [Char]
"    public R visit("
      , [Char]
packageAbsyn [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"." [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ RFun -> [Char]
forall a. IsFun a => a -> [Char]
funName RFun
fun
      , [Char]
" p, A arg) { return visitDefault(p, arg); }"
      ]
  | Bool
otherwise = []