From: Mart Lubbers Date: Fri, 26 Feb 2016 19:37:24 +0000 (+0100) Subject: update, parser kan expressies op binaire operatoren na, beginnetje gemaakt voor prese... X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=b4636110ab65f233ed40d4390b62c7799df3c949;p=cc1516.git update, parser kan expressies op binaire operatoren na, beginnetje gemaakt voor presentatie --- diff --git a/README.md b/README.md deleted file mode 100644 index b75222a..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cc1516 - -- Bouwen met `cpm make` diff --git a/deliverables/.gitignore b/deliverables/.gitignore new file mode 100644 index 0000000..1c934b1 --- /dev/null +++ b/deliverables/.gitignore @@ -0,0 +1,7 @@ +*.aux +*.fmt +*.log +*.nav +*.out +*.snm +*.toc diff --git a/deliverables/p1/Makefile b/deliverables/p1/Makefile new file mode 100644 index 0000000..dc5100d --- /dev/null +++ b/deliverables/p1/Makefile @@ -0,0 +1,17 @@ +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) diff --git a/deliverables/p1/p1.pdf b/deliverables/p1/p1.pdf new file mode 100644 index 0000000..10b2596 Binary files /dev/null and b/deliverables/p1/p1.pdf differ diff --git a/deliverables/p1/p1.tex b/deliverables/p1/p1.tex new file mode 100644 index 0000000..7aff91d --- /dev/null +++ b/deliverables/p1/p1.tex @@ -0,0 +1,4 @@ +%&p1 +\begin{document} +\frame{\titlepage} +\end{document} diff --git a/deliverables/p1/pre.tex b/deliverables/p1/pre.tex new file mode 100644 index 0000000..06184f2 --- /dev/null +++ b/deliverables/p1/pre.tex @@ -0,0 +1,19 @@ +\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} diff --git a/parse.dcl b/parse.dcl deleted file mode 100644 index 785dfbc..0000000 --- a/parse.dcl +++ /dev/null @@ -1,10 +0,0 @@ -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 diff --git a/parse.icl b/parse.icl deleted file mode 100644 index 5551f20..0000000 --- a/parse.icl +++ /dev/null @@ -1,11 +0,0 @@ -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" diff --git a/.gitignore b/src/.gitignore similarity index 100% rename from .gitignore rename to src/.gitignore diff --git a/Makefile b/src/Makefile similarity index 100% rename from Makefile rename to src/Makefile diff --git a/example.spl b/src/example.spl similarity index 100% rename from example.spl rename to src/example.spl diff --git a/lex.dcl b/src/lex.dcl similarity index 96% rename from lex.dcl rename to src/lex.dcl index a887374..0b064b4 100644 --- a/lex.dcl +++ b/src/lex.dcl @@ -29,6 +29,7 @@ from Data.Either import :: Either | AmpersandsToken // && | PipesToken // || | ArrowToken // -> + | EmptyListToken // [] //One character tokens | BraceOpenToken // ( | BraceCloseToken // ) @@ -54,4 +55,6 @@ from Data.Either import :: Either :: LexerOutput :== Either String [Token] +(===) :: TokenValue Token -> Bool + lexer :: [Char] -> LexerOutput diff --git a/lex.icl b/src/lex.icl similarity index 59% rename from lex.icl rename to src/lex.icl index de200df..b6e56d5 100644 --- a/lex.icl +++ b/src/lex.icl @@ -59,6 +59,7 @@ lex ['>':'=':xs] = ret GreaterEqToken xs 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 @@ -67,7 +68,7 @@ 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 @@ -78,3 +79,49 @@ lex t=:[x:xs] = case get x SingleCharTokens of | 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 diff --git a/main.icl b/src/main.icl similarity index 54% rename from main.icl rename to src/main.icl index ef5566a..9bc8d20 100644 --- a/main.icl +++ b/src/main.icl @@ -6,21 +6,12 @@ import StdBool 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 diff --git a/main.prj b/src/main.prj similarity index 90% rename from main.prj rename to src/main.prj index 1880ded..870e822 100644 --- a/main.prj +++ b/src/main.prj @@ -31,7 +31,6 @@ Global Link LinkMethod: Static GenerateRelocations: False - GenerateSymbolTable: False GenerateLinkMap: False LinkResources: False ResourceSource: @@ -422,7 +421,7 @@ OtherModules 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 @@ -436,7 +435,7 @@ OtherModules 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 @@ -450,7 +449,7 @@ OtherModules 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 @@ -464,7 +463,7 @@ OtherModules 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 @@ -478,7 +477,7 @@ OtherModules 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 @@ -492,7 +491,7 @@ OtherModules 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 @@ -506,7 +505,7 @@ OtherModules 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 @@ -520,7 +519,7 @@ OtherModules 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 @@ -534,7 +533,7 @@ OtherModules 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 @@ -548,7 +547,7 @@ OtherModules 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 @@ -562,7 +561,7 @@ OtherModules 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 @@ -576,7 +575,7 @@ OtherModules 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 @@ -590,7 +589,7 @@ OtherModules 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 @@ -604,7 +603,7 @@ OtherModules 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 @@ -618,7 +617,7 @@ OtherModules 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 @@ -632,7 +631,7 @@ OtherModules 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 @@ -646,7 +645,7 @@ OtherModules 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 diff --git a/src/parse.dcl b/src/parse.dcl new file mode 100644 index 0000000..3f42eda --- /dev/null +++ b/src/parse.dcl @@ -0,0 +1,40 @@ +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 diff --git a/src/parse.icl b/src/parse.icl new file mode 100644 index 0000000..fdcb9e3 --- /dev/null +++ b/src/parse.icl @@ -0,0 +1,88 @@ +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) diff --git a/yard.dcl b/src/yard.dcl similarity index 85% rename from yard.dcl rename to src/yard.dcl index a1bb2a3..76b6c17 100644 --- a/yard.dcl +++ b/src/yard.dcl @@ -1,21 +1,23 @@ 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 diff --git a/yard.icl b/src/yard.icl similarity index 69% rename from yard.icl rename to src/yard.icl index 1443325..2f3c90a 100644 --- a/yard.icl +++ b/src/yard.icl @@ -2,36 +2,34 @@ implementation module yard 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 @@ -41,7 +39,7 @@ fail = empty 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