File: IfThenElse.g

package info (click to toggle)
frown 0.6.1-14
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 9,956 kB
  • ctags: 271
  • sloc: haskell: 35,132; makefile: 228; csh: 35; yacc: 23
file content (57 lines) | stat: -rw-r--r-- 1,792 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{-

Solution to the dangling-else problem:

	frown --trace IfThenElse.g

Try

	start (lexer "if a then if a then a=b else a=c")

-}


module Dangling
where
import Char
import Monad

type Result                   =  []

instance MonadPlus IO where
    mzero                     =  fail "mzero"
    m `mplus` n               =  putStrLn "** choice" >> m >> putStrLn "** backtrack" >> n

--frown ts                      =  putStrLn "*** syntax error" >> return undefined
frown ts                      =  fail "syntax error"

%{

Terminal                      =  IF | THEN | ELSE | EQU | IDENT {String} | *EOF;
Nonterminal                   =  start | stat | matched | unmatched | expr;

start                         :  stat;
stat                          :  matched;
                              |  unmatched;
matched                       :  IF, expr, THEN, matched, ELSE, matched;
                              |  expr, EQU, expr;
unmatched                     :  IF, expr, THEN, stat;
                              |  IF, expr, THEN, matched, ELSE, unmatched;
expr                          :  IDENT {s};

}%

data Terminal                 =  IF | THEN | ELSE | EQU | IDENT String | EOF
	                         deriving (Show)

lexer                         :: String -> [Terminal]
lexer []                      =  [EOF]
lexer ('=' : cs)              =  EQU : lexer cs
lexer (c : cs)
    | isAlpha c               =  let (n, cs') = span isAlphaNum cs
                                 in  (case (c : n) of
                                          "if"   -> IF
                                          "then" -> THEN
                                          "else" -> ELSE
                                          s      -> IDENT s) : lexer cs'
    | otherwise               =  lexer cs