+++ /dev/null
-# cc1516
-
-- Bouwen met `cpm make`
--- /dev/null
+*.aux
+*.fmt
+*.log
+*.nav
+*.out
+*.snm
+*.toc
--- /dev/null
+LATEX:=pdflatex
+DOCUMENT:=p1
+
+.PHONY: all clean
+.SECONDARY: $(DOCUMENT).fmt
+
+all: $(DOCUMENT).pdf
+
+%.pdf: %.tex %.fmt
+ $(LATEX) $(basename $@)
+ $(LATEX) $(basename $@)
+
+%.fmt: pre.tex
+ $(LATEX) -ini -jobname="$(basename $@)" "&$(LATEX) $<\dump"
+
+clean:
+ $(RM) -v $(addprefix $(DOCUMENT).,aux fmt log nav out snm toc)
--- /dev/null
+%&p1
+\begin{document}
+\frame{\titlepage}
+\end{document}
--- /dev/null
+\documentclass{beamer}
+
+\AtBeginSection[]{%
+ \begin{frame}
+ \frametitle{Table of Contents}
+ \tableofcontents[currentsection]
+ \end{frame}
+}
+
+\title[P1]{Lexical Analysis and Parsing}
+%\subtitle{}
+\author[P. Jager, M. Lubbers]{Pim Jager\inst{1}\and Mart Lubbers\inst{1}}
+\institute[Radboud University]{%
+ \inst{1}%
+ Computer Science: Software Science\\
+ Radboud University
+}
+\subject{Parser}
+\date{\today}
+++ /dev/null
-definition module parse
-
-from Data.Either import :: Either
-
-from lex import :: LexerOutput, :: Token, :: TokenValue
-
-:: ParserOutput :== Either String AST
-:: AST = If | While //stub
-
-parse :: LexerOutput -> ParserOutput
+++ /dev/null
-implementation module parse
-
-import StdString
-import Data.Either
-
-import yard
-import lex
-
-parse :: LexerOutput -> ParserOutput
-parse (Left e) = Left ("Lexer error: " +++ e)
-parse (Right r) = Left "Parser not yet implemented"
| AmpersandsToken // &&
| PipesToken // ||
| ArrowToken // ->
+ | EmptyListToken // []
//One character tokens
| BraceOpenToken // (
| BraceCloseToken // )
:: LexerOutput :== Either String [Token]
+(===) :: TokenValue Token -> Bool
+
lexer :: [Char] -> LexerOutput
lex ['=':'=':xs] = ret EqualsToken xs
lex ['&':'&':xs] = ret AmpersandsToken xs
lex ['|':'|':xs] = ret PipesToken xs
+lex ['[':']':xs] = ret EmptyListToken xs
lex ['-':'>':xs] = ret ArrowToken xs
lex ['\'':x:'\'':xs] = ret (CharToken x) xs
lex ['\'':'\\':x:'\'':xs] = case get x EscapeMap of
lex ['-':t=:[x:xs]]
| isDigit x = let (n, r) = span isDigit t in
ret (NumberToken (toInt $ toString ['-':n])) r
-| otherwise = ret DashToken xs
+| otherwise = ret DashToken t
lex t=:[x:xs] = case get x SingleCharTokens of
(Just tok) = ret tok xs
Nothing
| isAlpha x = let (v, r) = span isIdent t in ret (IdentToken v) r
with isIdent c = isAlphanum c || c == '_'
| otherwise = err ("Unexpected character: " +++ toString x)
+
+
+(===) :: TokenValue Token -> Bool
+(===) (IdentToken _) (_, IdentToken _) = True
+(===) (NumberToken _) (_, NumberToken _) = True
+(===) (CharToken _) (_, CharToken _) = True
+(===) (VarToken) (_, VarToken) = True
+(===) (ReturnToken) (_, ReturnToken) = True
+(===) (IfToken) (_, IfToken) = True
+(===) (ElseToken) (_, ElseToken) = True
+(===) (WhileToken) (_, WhileToken) = True
+(===) (TrueToken) (_, TrueToken) = True
+(===) (FalseToken) (_, FalseToken) = True
+(===) (VoidToken) (_, VoidToken) = True
+(===) (IntTypeToken) (_, IntTypeToken) = True
+(===) (CharTypeToken) (_, CharTypeToken) = True
+(===) (BoolTypeToken) (_, BoolTypeToken) = True
+(===) (DoubleColonToken) (_, DoubleColonToken) = True
+(===) (NotEqualToken) (_, NotEqualToken) = True
+(===) (LesserEqToken) (_, LesserEqToken) = True
+(===) (GreaterEqToken) (_, GreaterEqToken) = True
+(===) (EqualsToken) (_, EqualsToken) = True
+(===) (AmpersandsToken) (_, AmpersandsToken) = True
+(===) (PipesToken) (_, PipesToken) = True
+(===) (ArrowToken) (_, ArrowToken) = True
+(===) (EmptyListToken) (_, EmptyListToken) = True
+(===) (BraceOpenToken) (_, BraceOpenToken) = True
+(===) (BraceCloseToken) (_, BraceCloseToken) = True
+(===) (CBraceOpenToken) (_, CBraceOpenToken) = True
+(===) (CBraceCloseToken) (_, CBraceCloseToken) = True
+(===) (SquareOpenToken) (_, SquareOpenToken) = True
+(===) (SquareCloseToken) (_, SquareCloseToken) = True
+(===) (CommaToken) (_, CommaToken) = True
+(===) (ColonToken) (_, ColonToken) = True
+(===) (SColonToken) (_, SColonToken) = True
+(===) (DotToken) (_, DotToken) = True
+(===) (PlusToken) (_, PlusToken) = True
+(===) (DashToken) (_, DashToken) = True
+(===) (StarToken) (_, StarToken) = True
+(===) (SlashToken) (_, SlashToken) = True
+(===) (PercentToken) (_, PercentToken) = True
+(===) (AssignmentToken) (_, AssignmentToken) = True
+(===) (LesserToken) (_, LesserToken) = True
+(===) (BiggerToken) (_, BiggerToken) = True
+(===) (ExclamationToken) (_, ExclamationToken) = True
+(===) _ _ = False
import parse
import lex
-//Start :: *World -> (ParserOutput, *World)
-Start = ""
-//Start w
-//# (out, w) = stdio w
-//# (toparse, out) = readEntireFile out
-//# (_, w) = fclose out w
-//= (lexer toparse, w)
-/*
-Start :: *World -> (ParserOutput, *World)
+Start :: *World -> (LexerOutput, ParserOutput, *World)
Start w
# (out, w) = stdio w
# (toparse, out) = readEntireFile out
# (_, w) = fclose out w
-= (parse (lexer toparse), w)
-*/
+= (lexer toparse, parse (lexer toparse), w)
readEntireFile :: *File -> *([Char], *File)
readEntireFile f
Link
LinkMethod: Static
GenerateRelocations: False
- GenerateSymbolTable: False
GenerateLinkMap: False
LinkResources: False
ResourceSource:
Fusion: False
Module
Name: Control.Applicative
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Control.Monad
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Either
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Foldable
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Func
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Functor
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.List
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Map
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Maybe
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Monoid
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Set
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Traversable
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Data.Void
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: System.IO
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Text
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Text.JSON
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
Fusion: False
Module
Name: Text.PPrint
- Dir: {Application}/lib/iTasks-SDK/Dependencies/clean-platform/src/libraries/OS-Independent
+ Dir: {Application}/lib/iTasks-SDK/Dependencies/Platform/OS-Independent
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
--- /dev/null
+definition module parse
+
+from Data.Either import :: Either
+from Data.Maybe import :: Maybe
+
+import lex
+
+:: ParserOutput :== Either String AST
+
+:: AST = AST [VarDecl] [FunDecl]
+:: VarDecl = VarDecl String Type Expr
+:: Type
+ = TupleType Type Type
+ | ListType Type
+ | IdType String
+ | IntType
+ | BoolType
+ | CharType
+ | VarType
+
+:: Expr
+ = VarExpr String (Maybe FieldSelector)
+ | Op2Expr Expr Op2 Expr //TODO, iets met associativiteit wat niet weet hoe
+ | Op1Expr Op1 Expr
+ | IntExpr Int
+ | CharExpr Char
+ | BoolExpr Bool
+ | EmptyListExpr
+ | TupleExpr Expr Expr
+
+:: FieldSelector = FieldHd | FieldTl | FieldFst | FieldSnd
+:: Op1 = UnNegation | UnMinus
+:: Op2 = BiPlus | BiMinus | BiTimes | BiDivide | BiMod | BiEquals | BiLesser |
+ BiGreater | BiLesserEq | BiGreaterEq | BiUnEqual | BiAnd | BiOr | BiCons
+
+//TODO
+
+:: FunDecl = Stub
+
+parse :: LexerOutput -> ParserOutput
--- /dev/null
+implementation module parse
+
+import StdString
+import StdTuple
+import StdList
+from StdFunc import const
+import Data.Either
+import Control.Monad
+import Control.Applicative
+import Data.Func
+
+import yard
+import lex
+
+parse :: LexerOutput -> ParserOutput
+parse (Left e) = Left $ toString $ LexError e
+parse (Right r) = case runParser parseProgram r of
+ (Right p, _) = Right p
+ (Left e, _) = Left $ toString e
+
+parseProgram :: Parser Token AST
+parseProgram = parseVar >>= \t.pure $ AST [t] []
+
+parseVar :: Parser Token VarDecl
+parseVar = parseType
+ >>= \t->parseIdent <* satTok AssignmentToken
+ >>= \i->parseExpr <* satTok SColonToken
+ >>= \e->pure $ VarDecl i t e
+
+parseType :: Parser Token Type
+parseType =
+ trans1 IntTypeToken IntType <|>
+ trans1 VarToken VarType <|>
+ trans1 CharTypeToken CharType <|>
+ trans1 BoolTypeToken BoolType <|>
+ (satTok SquareOpenToken *> parseType <* satTok SquareCloseToken
+ >>= \t.pure $ ListType t) <|>
+ (satTok BraceOpenToken *> parseType <* satTok CommaToken
+ >>= \t1->parseType <* satTok BraceCloseToken
+ >>= \t2->pure $ TupleType t1 t2) <|>
+ (parseIdent >>= \e.pure $ IdType e) <|>
+ empty
+
+parseExpr :: Parser Token Expr
+parseExpr =
+ (satTok BraceOpenToken *> parseExpr <* satTok BraceCloseToken) <|>
+ (satTok BraceOpenToken *> parseExpr <* satTok CommaToken
+ >>= \e1->parseExpr <* satTok BraceCloseToken
+ >>= \e2->pure $ TupleExpr e1 e2) <|>
+ trans1 EmptyListToken EmptyListExpr <|>
+ trans2 TrueToken (const $ BoolExpr True) <|>
+ trans2 FalseToken (const $ BoolExpr True) <|>
+ trans2 (NumberToken zero) (\(NumberToken i)->IntExpr i) <|>
+ trans2 (CharToken zero) (\(CharToken c)->CharExpr c) <|>
+ (parseOp1 >>= \o->parseExpr >>= \e.pure $ Op1Expr o e) <|>
+ (parseIdent >>= \i. parseFieldSelector >>= \f.pure $ VarExpr i f)
+
+parseOp1 :: Parser Token Op1
+parseOp1 = trans1 DashToken UnMinus <|>
+ trans1 ExclamationToken UnNegation
+
+parseOp2 :: Parser Token Op2
+parseOp2 = trans1 StarToken BiTimes <|> trans1 SlashToken BiDivide <|>
+ trans1 PercentToken BiMod <|> trans1 EqualsToken BiEquals <|>
+ trans1 LesserToken BiLesser <|> trans1 BiggerToken BiGreater <|>
+ trans1 LesserEqToken BiLesserEq <|> trans1 PlusToken BiPlus <|>
+ trans1 GreaterEqToken BiGreaterEq <|> trans1 DashToken BiMinus <|>
+ trans1 NotEqualToken BiUnEqual <|> trans1 AmpersandsToken BiAnd <|>
+ trans1 PipesToken BiOr <|> trans1 ColonToken BiCons
+
+parseFieldSelector :: Parser Token (Maybe FieldSelector)
+parseFieldSelector = optional (satTok DotToken *> (
+ (parseIdent >>= (\i.if (i == "hd") (pure FieldHd) empty)) <|>
+ (parseIdent >>= \i.if (i == "tl") (pure FieldTl) empty) <|>
+ (parseIdent >>= \i.if (i == "fst") (pure FieldFst) empty) <|>
+ (parseIdent >>= \i.if (i == "snd") (pure FieldSnd) empty)))
+
+trans2 :: TokenValue (TokenValue -> a) -> Parser Token a
+trans2 t f = satTok t >>= \(_, r).pure (f r)
+
+trans1 :: TokenValue a -> Parser Token a
+trans1 t r = trans2 t $ const r
+
+satTok :: TokenValue -> Parser Token Token
+satTok t = satisfy ((===) t)
+
+parseIdent :: Parser Token String
+parseIdent = trans2 (IdentToken []) (\(IdentToken e).toString e)
definition module yard
+from StdString import class toString
from Data.Either import :: Either
from StdClass import class Eq
from Data.Functor import class Functor
from Control.Monad import class Monad
from Control.Applicative import class Applicative, class Alternative
-:: Error = ParseException
+:: Error = ParseError | LexError String
:: Parser a b = Parser ([a] -> (Either Error b, [a]))
-runParser :: (Parser a b) [a] -> (Either Error b, [a])
-
instance Functor (Parser a)
instance Applicative (Parser a)
instance Monad (Parser a)
instance Alternative (Parser a)
+instance toString Error
+
+runParser :: (Parser a b) [a] -> (Either Error b, [a])
fail :: Parser a b
top :: Parser a a
satisfy :: (a -> Bool) -> Parser a a
import StdTuple
import StdClass
+import StdString
import Data.Functor
import Data.Either
import Control.Monad
import Control.Applicative
from Data.Func import $
+instance toString Error where
+ toString ParseError = "General parse error"
+ toString (LexError e) = "Lexer error: " +++ e
+
runParser :: (Parser a b) [a] -> (Either Error b, [a])
runParser (Parser f) i = f i
instance Functor (Parser a) where
- //fmap f m = liftM f m
- fmap g p = Parser \i -> case runParser p i of
- (Right r, rest) = (Right $ g r, rest)
- (Left e, rest) = (Left e, rest)
+ fmap f m = liftM f m
instance Applicative (Parser a) where
pure a = Parser \i -> (Right a, i)
- //(<*>) sf p = ap sf p
- (<*>) pf p = Parser \i -> case runParser pf i of
- (Right f, rest) = runParser (fmap f p) rest
- (Left e, rest) = (Left e, rest)
+ (<*>) sf p = ap sf p
instance Monad (Parser a) where
bind p f = Parser \i -> case runParser p i of
(Right r, rest) = runParser (f r) rest
(Left e, rest) = (Left e, rest)
-//some, many, optional and l
instance Alternative (Parser a) where
- empty = Parser \i -> (Left ParseException, i)
+ empty = Parser \i -> (Left ParseError, i)
(<|>) p1 p2 = Parser \i -> case runParser p1 i of
(Right r, rest) = (Right r, rest)
(Left _, rest) = runParser p2 i
top :: Parser a a
top = Parser \i -> case i of
- [] = (Left ParseException, [])
+ [] = (Left ParseError, [])
[x:xs] = (Right x, xs)
satisfy :: (a -> Bool) -> Parser a a