tools/PascalParser.hs
branch0.9.17
changeset 6366 1a49a8fcca56
parent 6357 52cb4807a78c
child 6386 7d7703b26bda
equal deleted inserted replaced
6360:eca20f8990e2 6366:1a49a8fcca56
    21 data Identifier = Identifier String
    21 data Identifier = Identifier String
    22     deriving Show
    22     deriving Show
    23 data TypesAndVars = TypesAndVars [TypeVarDeclaration]
    23 data TypesAndVars = TypesAndVars [TypeVarDeclaration]
    24     deriving Show
    24     deriving Show
    25 data TypeVarDeclaration = TypeDeclaration Identifier TypeDecl
    25 data TypeVarDeclaration = TypeDeclaration Identifier TypeDecl
    26     | VarDeclaration Bool ([Identifier], TypeDecl) (Maybe Expression)
    26     | VarDeclaration Bool ([Identifier], TypeDecl) (Maybe InitExpression)
    27     | FunctionDeclaration Identifier TypeDecl (Maybe Phrase)
    27     | FunctionDeclaration Identifier TypeDecl (Maybe Phrase)
    28     deriving Show
    28     deriving Show
    29 data TypeDecl = SimpleType Identifier
    29 data TypeDecl = SimpleType Identifier
    30     | RangeType Range
    30     | RangeType Range
    31     | Sequence [Identifier]
    31     | Sequence [Identifier]
    47 data Phrase = ProcCall Identifier [Expression]
    47 data Phrase = ProcCall Identifier [Expression]
    48         | IfThenElse Expression Phrase (Maybe Phrase)
    48         | IfThenElse Expression Phrase (Maybe Phrase)
    49         | WhileCycle Expression Phrase
    49         | WhileCycle Expression Phrase
    50         | RepeatCycle Expression [Phrase]
    50         | RepeatCycle Expression [Phrase]
    51         | ForCycle Identifier Expression Expression Phrase
    51         | ForCycle Identifier Expression Expression Phrase
    52         | WithBlock Expression Phrase
    52         | WithBlock Reference Phrase
    53         | Phrases [Phrase]
    53         | Phrases [Phrase]
    54         | SwitchCase Expression [(Expression, Phrase)] (Maybe Phrase)
    54         | SwitchCase Expression [(Expression, Phrase)] (Maybe Phrase)
    55         | Assignment Reference Expression
    55         | Assignment Reference Expression
    56     deriving Show
    56     deriving Show
    57 data Expression = Expression String
    57 data Expression = Expression String
    59     | PostfixOp String Expression
    59     | PostfixOp String Expression
    60     | BinOp String Expression Expression
    60     | BinOp String Expression Expression
    61     | StringLiteral String
    61     | StringLiteral String
    62     | CharCode String
    62     | CharCode String
    63     | NumberLiteral String
    63     | NumberLiteral String
       
    64     | FloatLiteral String
    64     | HexNumber String
    65     | HexNumber String
    65     | Reference Reference
    66     | Reference Reference
    66     | Null
    67     | Null
    67     deriving Show
    68     deriving Show
    68 data Reference = ArrayElement [Expression] Reference
    69 data Reference = ArrayElement [Expression] Reference
    69     | FunCall [Expression] Reference
    70     | FunCall [Expression] Reference
       
    71     | BuiltInFunCall [Expression] Reference
    70     | SimpleReference Identifier
    72     | SimpleReference Identifier
    71     | Dereference Reference
    73     | Dereference Reference
    72     | RecordField Reference Reference
    74     | RecordField Reference Reference
    73     | Address Reference
    75     | Address Reference
    74     deriving Show
    76     deriving Show
       
    77 data InitExpression = InitBinOp String InitExpression InitExpression
       
    78     | InitPrefixOp String InitExpression
       
    79     | InitReference Identifier
       
    80     | InitArray [InitExpression]
       
    81     | InitRecord [(Identifier, InitExpression)]
       
    82     | InitFloat String
       
    83     | InitNumber String
       
    84     | InitHexNumber String
       
    85     | InitString String
       
    86     | InitChar String
       
    87     | InitNull
       
    88     deriving Show
       
    89 
    75     
    90     
    76 pascalLanguageDef
    91 pascalLanguageDef
    77     = emptyDef
    92     = emptyDef
    78     { commentStart   = "(*"
    93     { commentStart   = "(*"
    79     , commentEnd     = "*)"
    94     , commentEnd     = "*)"
    86             , "implementation", "and", "or", "xor", "shl"
   101             , "implementation", "and", "or", "xor", "shl"
    87             , "shr", "while", "do", "repeat", "until", "case", "of"
   102             , "shr", "while", "do", "repeat", "until", "case", "of"
    88             , "type", "var", "const", "out", "array", "packed"
   103             , "type", "var", "const", "out", "array", "packed"
    89             , "procedure", "function", "with", "for", "to"
   104             , "procedure", "function", "with", "for", "to"
    90             , "downto", "div", "mod", "record", "set", "nil"
   105             , "downto", "div", "mod", "record", "set", "nil"
    91             , "string", "shortstring"
   106             , "string", "shortstring", "succ", "pred", "low"
       
   107             , "high"
    92             ]
   108             ]
    93     , reservedOpNames= [] 
   109     , reservedOpNames= [] 
    94     , caseSensitive  = False   
   110     , caseSensitive  = False   
    95     }
   111     }
    96     
   112     
   181     t <- typeDecl <?> "variable type declaration"
   197     t <- typeDecl <?> "variable type declaration"
   182     comments
   198     comments
   183     init <- option Nothing $ do
   199     init <- option Nothing $ do
   184         char '='
   200         char '='
   185         comments
   201         comments
   186         e <- expression
   202         e <- initExpression
   187         comments
   203         comments
   188         return (Just e)
   204         return (Just e)
   189     return $ VarDeclaration False (ids, t) init
   205     return $ VarDeclaration False (ids, t) init
   190 
   206 
   191 
   207 
   202             comments
   218             comments
   203             t <- typeDecl
   219             t <- typeDecl
   204             return ()
   220             return ()
   205         char '='
   221         char '='
   206         comments
   222         comments
   207         e <- expression
   223         e <- initExpression
   208         comments
   224         comments
   209         return $ VarDeclaration False ([i], UnknownType) (Just e)
   225         return $ VarDeclaration False ([i], UnknownType) (Just e)
   210         
   226         
   211 typeDecl = choice [
   227 typeDecl = choice [
   212     char '^' >> typeDecl >>= return . PointerTo
   228     char '^' >> typeDecl >>= return . PointerTo
   213     , try (string "shortstring") >> return String
   229     , try (string "shortstring") >> return String
   214     , arrayDecl
   230     , arrayDecl
   215     , recordDecl
   231     , recordDecl
       
   232     , sequenceDecl >>= return . Sequence
       
   233     , try (identifier pas) >>= return . SimpleType . Identifier
   216     , rangeDecl >>= return . RangeType
   234     , rangeDecl >>= return . RangeType
   217     , sequenceDecl >>= return . Sequence
       
   218     , identifier pas >>= return . SimpleType . Identifier
       
   219     ] <?> "type declaration"
   235     ] <?> "type declaration"
   220     where
   236     where
   221     arrayDecl = do
   237     arrayDecl = do
   222         try $ string "array"
   238         try $ string "array"
   223         comments
   239         comments
   334                 optional $ typeVarDeclaration True
   350                 optional $ typeVarDeclaration True
   335                 comments
   351                 comments
   336                 liftM Just functionBody
   352                 liftM Just functionBody
   337                 else
   353                 else
   338                 return Nothing
   354                 return Nothing
   339         return $ [FunctionDeclaration i ret Nothing]
   355         return $ [FunctionDeclaration i ret b]
   340 
   356 
   341 program = do
   357 program = do
   342     string "program"
   358     string "program"
   343     comments
   359     comments
   344     name <- iD
   360     name <- iD
   369 
   385 
   370 expression = buildExpressionParser table term <?> "expression"
   386 expression = buildExpressionParser table term <?> "expression"
   371     where
   387     where
   372     term = comments >> choice [
   388     term = comments >> choice [
   373         parens pas $ expression 
   389         parens pas $ expression 
       
   390         , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . NumberLiteral . show) i
       
   391         , try $ float pas >>= return . FloatLiteral . show
   374         , try $ integer pas >>= return . NumberLiteral . show
   392         , try $ integer pas >>= return . NumberLiteral . show
   375         , stringLiteral pas >>= return . StringLiteral
   393         , stringLiteral pas >>= return . StringLiteral
   376         , char '#' >> many digit >>= return . CharCode
   394         , char '#' >> many digit >>= return . CharCode
   377         , char '$' >> many hexDigit >>= return . HexNumber
   395         , char '$' >> many hexDigit >>= return . HexNumber
   378         , try $ string "nil" >> return Null
   396         , try $ string "nil" >> return Null
   398           ]
   416           ]
   399         , [  Infix (try $ string "and" >> return (BinOp "and")) AssocLeft
   417         , [  Infix (try $ string "and" >> return (BinOp "and")) AssocLeft
   400            , Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
   418            , Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
   401            , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
   419            , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
   402           ]
   420           ]
   403         , [  Infix (try $ string "shl" >> return (BinOp "and")) AssocNone
   421         , [  Infix (try $ string "shl" >> return (BinOp "shl")) AssocNone
   404            , Infix (try $ string "shr" >> return (BinOp "or")) AssocNone
   422            , Infix (try $ string "shr" >> return (BinOp "shr")) AssocNone
   405           ]
   423           ]
   406         , [Prefix (try (string "not") >> return (PrefixOp "not"))]
   424         , [Prefix (try (string "not") >> return (PrefixOp "not"))]
   407         ]
   425         ]
   408     
   426     
   409 phrasesBlock = do
   427 phrasesBlock = do
   457     return $ WhileCycle e o
   475     return $ WhileCycle e o
   458 
   476 
   459 withBlock = do
   477 withBlock = do
   460     try $ string "with"
   478     try $ string "with"
   461     comments
   479     comments
   462     e <- expression
   480     r <- reference
   463     comments
   481     comments
   464     string "do"
   482     string "do"
   465     comments
   483     comments
   466     o <- phrase
   484     o <- phrase
   467     return $ WithBlock e o
   485     return $ WithBlock r o
   468     
   486     
   469 repeatCycle = do
   487 repeatCycle = do
   470     try $ string "repeat"
   488     try $ string "repeat"
   471     comments
   489     comments
   472     o <- many phrase
   490     o <- many phrase
   541             comments
   559             comments
   542             u <- (iD >>= \i -> comments >> return i) `sepBy1` (char ',' >> comments)
   560             u <- (iD >>= \i -> comments >> return i) `sepBy1` (char ',' >> comments)
   543             char ';'
   561             char ';'
   544             comments
   562             comments
   545             return u
   563             return u
       
   564 
       
   565 initExpression = buildExpressionParser table term <?> "initialization expression"
       
   566     where
       
   567     term = comments >> choice [
       
   568         try $ parens pas (commaSep pas $ initExpression) >>= return . InitArray
       
   569         , parens pas (semiSep pas $ recField) >>= return . InitRecord
       
   570         , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . InitNumber . show) i
       
   571         , try $ float pas >>= return . InitFloat . show
       
   572         , stringLiteral pas >>= return . InitString
       
   573         , char '#' >> many digit >>= return . InitChar
       
   574         , char '$' >> many hexDigit >>= return . InitHexNumber
       
   575         , try $ string "nil" >> return InitNull
       
   576         , iD >>= return . InitReference
       
   577         ]
       
   578         
       
   579     recField = do
       
   580         i <- iD
       
   581         spaces
       
   582         char ':'
       
   583         spaces
       
   584         e <- initExpression
       
   585         spaces
       
   586         return (i ,e)
       
   587 
       
   588     table = [ 
       
   589           [  Infix (char '*' >> return (InitBinOp "*")) AssocLeft
       
   590            , Infix (char '/' >> return (InitBinOp "/")) AssocLeft
       
   591            , Infix (try (string "div") >> return (InitBinOp "div")) AssocLeft
       
   592            , Infix (try (string "mod") >> return (InitBinOp "mod")) AssocLeft
       
   593           ]
       
   594         , [  Infix (char '+' >> return (InitBinOp "+")) AssocLeft
       
   595            , Infix (char '-' >> return (InitBinOp "-")) AssocLeft
       
   596            , Prefix (char '-' >> return (InitPrefixOp "-"))
       
   597           ]
       
   598         , [  Infix (try (string "<>") >> return (InitBinOp "<>")) AssocNone
       
   599            , Infix (try (string "<=") >> return (InitBinOp "<=")) AssocNone
       
   600            , Infix (try (string ">=") >> return (InitBinOp ">=")) AssocNone
       
   601            , Infix (char '<' >> return (InitBinOp "<")) AssocNone
       
   602            , Infix (char '>' >> return (InitBinOp ">")) AssocNone
       
   603            , Infix (char '=' >> return (InitBinOp "=")) AssocNone
       
   604           ]
       
   605         , [  Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft
       
   606            , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft
       
   607            , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft
       
   608           ]
       
   609         , [  Infix (try $ string "shl" >> return (InitBinOp "and")) AssocNone
       
   610            , Infix (try $ string "shr" >> return (InitBinOp "or")) AssocNone
       
   611           ]
       
   612         , [Prefix (try (string "not") >> return (InitPrefixOp "not"))]
       
   613         ]
       
   614