Line No. | Rev | Author | Line |
---|---|---|---|
1 | 1 | paulosilva | |
2 | {-# LANGUAGE TypeOperators, FlexibleContexts #-} | ||
3 | {-# OPTIONS_GHC -Wall #-} | ||
4 | |||
5 | ------------------------------------------------------------------------------- | ||
6 | |||
7 | {- | | ||
8 | Module : Language.Combinator.Parser | ||
9 | Description : | ||
10 | Copyright : (c) Paulo Silva | ||
11 | License : LGPL | ||
12 | |||
13 | Maintainer : paufil@di.uminho.pt | ||
14 | Stability : experimental | ||
15 | Portability : portable | ||
16 | |||
17 | <description of the module> | ||
18 | -} | ||
19 | |||
20 | ------------------------------------------------------------------------------- | ||
21 | |||
22 | module Language.Combinator.Parser ( | ||
23 | parser, | ||
24 | parseComb | ||
25 | ) where | ||
26 | |||
27 | import Control.GalcError | ||
28 | import Control.Monad.Error | ||
29 | import Language.Combinator.Syntax | ||
30 | import qualified Language.Derivation.Parser as D | ||
31 | import Text.ParserCombinators.Parsec | ||
32 | import Text.ParserCombinators.Parsec.Language | ||
33 | import qualified Text.ParserCombinators.Parsec.Token as P | ||
34 | |||
35 | ------------------------------------------------------------------------------- | ||
36 | |||
37 | type CombParser = Parser Combinator | ||
38 | |||
39 | ------------------------------------------------------------------------------- | ||
40 | |||
41 | reservNames :: [String] | ||
42 | reservNames = combinators | ||
43 | |||
44 | ------------------------------------------------------------------------------- | ||
45 | |||
46 | lexer :: P.TokenParser st | ||
47 | lexer = P.makeTokenParser $ emptyDef { P.reservedNames = reservNames } | ||
48 | |||
49 | ------------------------------------------------------------------------------- | ||
50 | |||
51 | reserved :: String -> CharParser st () | ||
52 | reserved = P.reserved lexer | ||
53 | |||
54 | whiteSpace :: CharParser st () | ||
55 | whiteSpace = P.whiteSpace lexer | ||
56 | |||
57 | parens :: CharParser st Combinator -> CharParser st Combinator | ||
58 | parens = P.parens lexer | ||
59 | |||
60 | ------------------------------------------------------------------------------- | ||
61 | |||
62 | parser :: MonadError GalcError m => String -> m Combinator | ||
63 | parser = either2error (ParsingError . show) . parse mainCombParser "" | ||
64 | |||
65 | ------------------------------------------------------------------------------- | ||
66 | |||
67 | mainCombParser :: CombParser | ||
68 | mainCombParser = do | ||
69 | whiteSpace | ||
70 | t <- parseComb | ||
71 | eof | ||
72 | return t | ||
73 | |||
74 | ------------------------------------------------------------------------------- | ||
75 | |||
76 | parseComb :: CombParser | ||
77 | parseComb = | ||
78 | parens parseComb <|> | ||
79 | parseNop <|> | ||
80 | parseFail <|> | ||
81 | parseSeq <|> | ||
82 | parseChoice <|> | ||
83 | parseLChoice <|> | ||
84 | parseMany <|> | ||
85 | parseMany1 <|> | ||
86 | parseTry <|> | ||
87 | parseOnce <|> | ||
88 | parseEverywhere <|> | ||
89 | parseEverywhere' <|> | ||
90 | parseInnermost <|> | ||
91 | parseAll <|> | ||
92 | parseOne <|> | ||
93 | parseRule | ||
94 | |||
95 | ------------------------------------------------------------------------------- | ||
96 | |||
97 | parseNop :: CombParser | ||
98 | parseNop = do | ||
99 | reserved "nop" | ||
100 | return Nop | ||
101 | |||
102 | ------------------------------------------------------------------------------- | ||
103 | |||
104 | parseFail :: CombParser | ||
105 | parseFail = do | ||
106 | reserved "fail" | ||
107 | return Fail | ||
108 | |||
109 | ------------------------------------------------------------------------------- | ||
110 | |||
111 | parseSeq :: CombParser | ||
112 | parseSeq = do | ||
113 | reserved "seq" | ||
114 | c1 <- parseComb | ||
115 | c2 <- parseComb | ||
116 | return $ Seq c1 c2 | ||
117 | |||
118 | ------------------------------------------------------------------------------- | ||
119 | |||
120 | parseChoice :: CombParser | ||
121 | parseChoice = do | ||
122 | reserved "choice" | ||
123 | c1 <- parseComb | ||
124 | c2 <- parseComb | ||
125 | return $ Choice c1 c2 | ||
126 | |||
127 | ------------------------------------------------------------------------------- | ||
128 | |||
129 | parseLChoice :: CombParser | ||
130 | parseLChoice = do | ||
131 | reserved "lchoice" | ||
132 | c1 <- parseComb | ||
133 | c2 <- parseComb | ||
134 | return $ LChoice c1 c2 | ||
135 | |||
136 | ------------------------------------------------------------------------------- | ||
137 | |||
138 | parseMany :: CombParser | ||
139 | parseMany = do | ||
140 | reserved "many" | ||
141 | c <- parseComb | ||
142 | return $ Many c | ||
143 | |||
144 | ------------------------------------------------------------------------------- | ||
145 | |||
146 | parseMany1 :: CombParser | ||
147 | parseMany1 = do | ||
148 | reserved "many1" | ||
149 | c <- parseComb | ||
150 | return $ Many1 c | ||
151 | |||
152 | ------------------------------------------------------------------------------- | ||
153 | |||
154 | parseTry :: CombParser | ||
155 | parseTry = do | ||
156 | reserved "try" | ||
157 | c <- parseComb | ||
158 | return $ Try c | ||
159 | |||
160 | ------------------------------------------------------------------------------- | ||
161 | |||
162 | parseOnce :: CombParser | ||
163 | parseOnce = do | ||
164 | reserved "once" | ||
165 | c <- parseComb | ||
166 | return $ Once c | ||
167 | |||
168 | ------------------------------------------------------------------------------- | ||
169 | |||
170 | parseEverywhere :: CombParser | ||
171 | parseEverywhere = do | ||
172 | reserved "everywhere" | ||
173 | c <- parseComb | ||
174 | return $ Everywhere c | ||
175 | |||
176 | ------------------------------------------------------------------------------- | ||
177 | |||
178 | parseEverywhere' :: CombParser | ||
179 | parseEverywhere' = do | ||
180 | 7 | paulosilva | reserved "everywhere'" |
181 | 1 | paulosilva | c <- parseComb |
182 | return $ Everywhere' c | ||
183 | |||
184 | ------------------------------------------------------------------------------- | ||
185 | |||
186 | parseInnermost :: CombParser | ||
187 | parseInnermost = do | ||
188 | reserved "innermost" | ||
189 | c <- parseComb | ||
190 | return $ Innermost c | ||
191 | |||
192 | ------------------------------------------------------------------------------- | ||
193 | |||
194 | parseAll :: CombParser | ||
195 | parseAll = do | ||
196 | reserved "all" | ||
197 | c <- parseComb | ||
198 | return $ All c | ||
199 | |||
200 | ------------------------------------------------------------------------------- | ||
201 | |||
202 | parseOne :: CombParser | ||
203 | parseOne = do | ||
204 | reserved "one" | ||
205 | c <- parseComb | ||
206 | return $ One c | ||
207 | |||
208 | ------------------------------------------------------------------------------- | ||
209 | |||
210 | parseRule :: CombParser | ||
211 | parseRule = do | ||
212 | drv <- D.parseDeriv | ||
213 | return $ Rule drv | ||
214 | |||
215 | ------------------------------------------------------------------------------- |