[project @ 2002-10-29 04:00:59 by mthomas]
[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         : '[' ']'                       { [] }
32         | '[' pkgs ']'                  { reverse $2 }
33
34 pkgs    :: { [ PackageConfig ] }
35         : pkg                           { [ $1 ] }
36         | pkgs ',' pkg                  { $3 : $1 }
37
38 pkg     :: { PackageConfig }
39         : CONID '{' fields '}'          { $3 defaultPackageConfig }
40
41 fields  :: { PackageConfig -> PackageConfig }
42         : field                         { \p -> $1 p }
43         | fields ',' field              { \p -> $1 ($3 p) }
44
45 field   :: { PackageConfig -> PackageConfig }
46         : VARID '=' STRING              
47                  {\p -> case $1 of
48                    "name" -> p{name = $3}
49                    _      -> error "unknown key in config file" }
50                         
51         | VARID '=' strlist             
52                 {\p -> case $1 of
53                         "import_dirs"     -> p{import_dirs     = $3}
54                         "library_dirs"    -> p{library_dirs    = $3}
55                         "hs_libraries"    -> p{hs_libraries    = $3}
56                         "extra_libraries" -> p{extra_libraries = $3}
57                         "include_dirs"    -> p{include_dirs    = $3}
58                         "c_includes"      -> p{c_includes      = $3}
59                         "package_deps"    -> p{package_deps    = $3}
60                         "extra_ghc_opts"  -> p{extra_ghc_opts  = $3}
61                         "extra_cc_opts"   -> p{extra_cc_opts   = $3}
62                         "extra_ld_opts"   -> p{extra_ld_opts   = $3}
63                         "framework_dirs"  -> p{framework_dirs  = $3}
64                         "extra_frameworks"-> p{extra_frameworks= $3}
65                         _other            -> p
66                 }
67
68 strlist :: { [String] }
69         : '[' ']'                       { [] }
70         | '[' strs ']'                  { reverse $2 }
71
72 strs    :: { [String] }
73         : STRING                        { [ $1 ] }
74         | strs ',' STRING               { $3 : $1 }
75
76 {
77 data Token =
78         ITocurly
79     |   ITccurly
80     |   ITobrack
81     |   ITcbrack
82     |   ITcomma
83     |   ITequal
84     |   ITvarid String
85     |   ITconid String
86     |   ITstring String
87
88 lexer :: String -> [Token]
89
90 lexer [] = []
91 lexer ('{':cs) = ITocurly : lexer cs
92 lexer ('}':cs) = ITccurly : lexer cs
93 lexer ('[':cs) = ITobrack : lexer cs
94 lexer (']':cs) = ITcbrack : lexer cs
95 lexer (',':cs) = ITcomma : lexer cs
96 lexer ('=':cs) = ITequal : lexer cs
97 lexer ('"':cs) = lexString cs ""
98 lexer (c:cs)
99     | isSpace c = lexer cs
100     | isAlpha c = lexID (c:cs) where
101 lexer _ = error "Unexpected token"
102
103 lexID cs = (if isUpper (head cs) then ITconid else ITvarid) id : lexer rest
104     where
105         (id,rest) = break (\c -> c /= '_' && not (isAlphaNum c)) cs
106
107 lexString ('"':cs) s = ITstring (reverse s) : lexer cs
108 lexString ('\\':c:cs) s = lexString cs (c:s)
109 lexString (c:cs) s = lexString cs (c:s)
110
111 happyError _ = error "Couldn't parse package configuration."
112
113 parsePackageConfig :: String -> [PackageConfig]
114 parsePackageConfig = parse . lexer
115
116 parseOnePackageConfig :: String -> PackageConfig
117 parseOnePackageConfig = parseOne . lexer
118 }