[project @ 2002-06-13 23:31:55 by sof]
[ghc-hetmet.git] / ghc / utils / ghc-pkg / ParsePkgConfLite.y
1 {
2 -- This parser is based on ParsedPkgConf.y in compiler/main/
3 -- It's supposed to do the same thing, but without depending on other GHC modules.
4 -- The disadvantage is the less sophisticated error reporting, and it's probably
5 -- slower because it doesn't use FastStrings.
6
7 module ParsePkgConfLite{- ( parsePackageConfig, parseOnePackageConfig ) -}where
8
9 import Package  ( PackageConfig(..), defaultPackageConfig )
10 import Char(isSpace, isAlpha, isAlphaNum, isUpper)
11 import List(break)
12 }
13
14 %token
15  '{'            { ITocurly }
16  '}'            { ITccurly }
17  '['            { ITobrack }
18  ']'            { ITcbrack }
19  ','            { ITcomma }
20  '='            { ITequal }
21  VARID          { ITvarid    $$ }
22  CONID          { ITconid    $$ }
23  STRING         { ITstring   $$ }
24
25 %name parse pkgconf
26 %name parseOne pkg
27 %tokentype { Token }
28 %%
29
30 pkgconf :: { [ PackageConfig ] }
31         : '[' pkgs ']'                  { reverse $2 }
32
33 pkgs    :: { [ PackageConfig ] }
34         : pkg                           { [ $1 ] }
35         | pkgs ',' pkg                  { $3 : $1 }
36
37 pkg     :: { PackageConfig }
38         : CONID '{' fields '}'          { $3 defaultPackageConfig }
39
40 fields  :: { PackageConfig -> PackageConfig }
41         : field                         { \p -> $1 p }
42         | fields ',' field              { \p -> $1 ($3 p) }
43
44 field   :: { PackageConfig -> PackageConfig }
45         : VARID '=' STRING              
46                  {\p -> case $1 of
47                    "name" -> p{name = $3}
48                    _      -> error "unkown key in config file" }
49                         
50         | VARID '=' strlist             
51                 {\p -> case $1 of
52                         "import_dirs"     -> p{import_dirs     = $3}
53                         "library_dirs"    -> p{library_dirs    = $3}
54                         "hs_libraries"    -> p{hs_libraries    = $3}
55                         "extra_libraries" -> p{extra_libraries = $3}
56                         "include_dirs"    -> p{include_dirs    = $3}
57                         "c_includes"      -> p{c_includes      = $3}
58                         "package_deps"    -> p{package_deps    = $3}
59                         "extra_ghc_opts"  -> p{extra_ghc_opts  = $3}
60                         "extra_cc_opts"   -> p{extra_cc_opts   = $3}
61                         "extra_ld_opts"   -> p{extra_ld_opts   = $3}
62                         "framework_dirs"  -> p{framework_dirs  = $3}
63                         "extra_frameworks"-> p{extra_frameworks= $3}
64                         _other            -> p
65                 }
66
67 strlist :: { [String] }
68         : '[' ']'                       { [] }
69         | '[' strs ']'                  { reverse $2 }
70
71 strs    :: { [String] }
72         : STRING                        { [ $1 ] }
73         | strs ',' STRING               { $3 : $1 }
74
75 {
76 data Token =
77         ITocurly
78     |   ITccurly
79     |   ITobrack
80     |   ITcbrack
81     |   ITcomma
82     |   ITequal
83     |   ITvarid String
84     |   ITconid String
85     |   ITstring String
86
87 lexer :: String -> [Token]
88
89 lexer [] = []
90 lexer ('{':cs) = ITocurly : lexer cs
91 lexer ('}':cs) = ITccurly : lexer cs
92 lexer ('[':cs) = ITobrack : lexer cs
93 lexer (']':cs) = ITcbrack : lexer cs
94 lexer (',':cs) = ITcomma : lexer cs
95 lexer ('=':cs) = ITequal : lexer cs
96 lexer ('"':cs) = lexString cs ""
97 lexer (c:cs)
98     | isSpace c = lexer cs
99     | isAlpha c = lexID (c:cs) where
100 lexer _ = error "Unexpected token"
101
102 lexID cs = (if isUpper (head cs) then ITconid else ITvarid) id : lexer rest
103     where
104         (id,rest) = break (\c -> c /= '_' && not (isAlphaNum c)) cs
105
106 lexString ('"':cs) s = ITstring (reverse s) : lexer cs
107 lexString ('\\':c:cs) s = lexString cs (c:s)
108 lexString (c:cs) s = lexString cs (c:s)
109
110 happyError _ = error "Couldn't parse package configuration."
111
112 parsePackageConfig :: String -> [PackageConfig]
113 parsePackageConfig = parse . lexer
114
115 parseOnePackageConfig :: String -> PackageConfig
116 parseOnePackageConfig = parseOne . lexer
117 }