diff options
author | Yuchen Pei <me@ypei.me> | 2018-01-10 14:12:44 +0100 |
---|---|---|
committer | Yuchen Pei <me@ypei.me> | 2018-01-10 14:12:44 +0100 |
commit | 99aa10bc83791237df047fff073c834c39d2a526 (patch) | |
tree | bde217200b1a469b5952934ef26ae06bce796c1d | |
parent | 2b1e8b34016e9357fff2a6b6ef54ead7c68f1cfc (diff) |
checkpoint
-rw-r--r-- | projects/10/JackParser.hs | 124 |
1 files changed, 95 insertions, 29 deletions
diff --git a/projects/10/JackParser.hs b/projects/10/JackParser.hs index d23b878..be5797d 100644 --- a/projects/10/JackParser.hs +++ b/projects/10/JackParser.hs @@ -7,18 +7,11 @@ import Text.Parsec.Combinator import Data.Functor.Identity import Data.Either ---turingParse :: Stream s Identity Char => Parsec s () (Int, Char, Rule) ---solve1 xs = let (initN, initSt, rule) = fromRight (0, 'A', Map.empty) $ parse turingParse "" xs in - --sum $ run initN 0 initSt [0] rule - data JClass = JClass JIdentifier [JClassVarDec] [JSubroutineDec] deriving (Show, Eq) data JClassVarDec = JClassVarDec JClassVarScope JTypeAndId deriving (Show, Eq) data JSubroutineDec = JSubroutineDec JSubroutineHeader JSubroutineBody deriving (Show, Eq) -data JSubroutineHeader = JSubroutineHeader JSubroutineType JTypeAndId [JParameter] deriving (Show, Eq) -data JSubroutineBody = JSubroutineBody [JVarDec] [JStatement] deriving (Show, Eq) -data JClassVarScope = JStatic | JField deriving (Show, Eq) -data JType = JInt | JChar | JBoolean | JVoid deriving (Show, Eq) -data JSubroutineType = JConstructor | JFunction | JMethod deriving (Show, Eq) +data JSubroutineHeader = JSubroutineHeader JSubroutineType JTypeAndId [JTypeAndId] deriving (Show, Eq) +data JSubroutineBody = JSubroutineBody [JTypeAndId] [JStatement] deriving (Show, Eq) data JStatement = JLetStatment JLeftVarId JExpression | JIfStatement JExpression [JStatement] (Maybe [JStatement]) | JWhileStatment JExpression [JStatement] @@ -39,10 +32,13 @@ data JSubroutineCall = JSubroutineCall JIdentifier (Maybe JIdentifier) [JExpress type JBOp = Char type JUOp = Char type JIdentifier = [Char] -type JackParser = Parsec [Char] () type JTypeAndId = (JType, JIdentifier) -type JParameter = JTypeAndId -type JVarDec = JTypeAndId +--type JParameter = JTypeAndId +--type JVarDec = JTypeAndId +type JClassVarScope = [Char] +type JType = [Char] +type JSubroutineType = [Char] +type JackParser = Parsec [Char] () binaryOpChars = "+-*/&|<>=" @@ -55,14 +51,12 @@ subroutineTypeStrs = ["constructor", "function", "method"] alphaUnderscore = ['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['_'] alphaNumUnderscore = alphaUnderscore ++ ['0'..'9'] -str2JType xs = case xs of "int" -> JInt; "char" -> JChar; "boolean" -> JBoolean; "void" -> JVoid; -str2JClassVarScope xs = case xs of "static" -> JStatic; "field" -> JField; -str2JSubroutineType xs = case xs of "constructor" -> JConstructor; "function" -> JFunction; "method" -> JMethod; +--str2JType xs = case xs of "int" -> JInt; "char" -> JChar; "boolean" -> JBoolean; "void" -> JVoid; +--str2JClassVarScope xs = case xs of "static" -> JStatic; "field" -> JField; +--str2JSubroutineType xs = case xs of "constructor" -> JConstructor; "function" -> JFunction; "method" -> JMethod; parse' parser = parse parser "" -skipSpaces = space >> skipMany space - jack = jClass jClass :: JackParser JClass @@ -75,13 +69,16 @@ jUOp :: JackParser JUOp jUOp = oneOf unaryOpChars jType :: JackParser JType -jType = fmap str2JType $ choice $ fmap string typeStrs +jType = choice $ string <$> typeStrs jType' :: JackParser JType -jType' = fmap str2JType $ choice $ fmap string typeStrs' +jType' = choice $ string <$> typeStrs' jClassVarScope :: JackParser JClassVarScope -jClassVarScope = fmap str2JClassVarScope $ choice $ fmap string classVarScopeStrs +jClassVarScope = choice $ string <$> classVarScopeStrs + +jSubroutineType :: JackParser JSubroutineType +jSubroutineType = choice $ string <$> subroutineTypeStrs jIdentifier :: JackParser [Char] jIdentifier = do @@ -92,29 +89,98 @@ jIdentifier = do jClassVarDec :: JackParser JClassVarDec jClassVarDec = do scope <- jClassVarScope - skipSpaces - typeAndId <- jTypeAndId + many1 space + typeAndId <- jVarDec many space >> char ';' return $ JClassVarDec scope typeAndId jTypeAndId :: JackParser JTypeAndId jTypeAndId = do type_ <- jType' - skipSpaces + many1 space id <- jIdentifier return (type_, id) -jParameter = many space >> jTypeAndId <* many space -jSubroutineType :: JackParser JSubroutineType -jSubroutineType = fmap str2JSubroutineType $ choice $ fmap string subroutineTypeStrs +jParameter :: JackParser JParameter +jParameter = many space >> jTypeAndId <* many space -{-- jSubroutineHeader :: JackParser JSubroutineHeader jSubroutineHeader = do subtype <- jSubroutineType - skipSpaces + many1 space typeAndId <- jTypeAndId char '(' params <- sepBy jParameter (char ',') char ')' ---} + return $ JSubroutineHeader subtype typeAndId params + +jTerm :: JackParser JTerm +jTerm = choice [jIntConst, jStrConst, jKeywordConst, jLeftVarId, jTermCall, jTermExp, jUnaryOpTerm, jTermInBraces] + +jIntConst :: JackParser JTerm +jIntConst = JIntConst <$> (read <$> many1 digit) + +jStrConst :: JackParser JTerm +jStrConst = JStrConst <$> between (char '"') (char '"') (many $ noneOf "\"") + +jKeywordConst :: JackParser JTerm +jKeywordConst = JKeywordConst <$> (choice $ string <$> keywordConstStrs) + +jLeftVarId :: JackParser JTerm +jLeftVarId = do + id <- jIdentifier + maybeArray <- option Nothing $ try (char '[' >> jExpression <* char ']') + return JLeftVarId id maybeArray + +jTermCall :: JackParser JTerm +jTermCall = JTermCall <$> jSubroutineCall + +jTermExp :: JackParser JTerm +jTermExp = JTermExp <$> jExpression + +jUnaryOpTerm :: JackParser JTerm +jUnaryOpTerm = do + op <- oneOf unaryOpChars + many space + term <- JTerm + return $ JUnaryOpTerm op term + +jTermInBraces :: JackParser JTerm +jTermInBraces = between (char '(') (char ')') jTerm + +jExpression :: JackParser JExpression +jExpression = do + x <- jTerm + xs <- many jOpAndTerm + return $ JExpression x xs + +jOpAndTerm :: JackParser (jBOp, jTerm) +jOpAndTerm = do + op <- many space >> jBOp + term <- many space >> jTerm + return (op, term) + +jClass :: JackParser JClass +jClass = do + string "class" >> many space >> char '{' >> many space + id <- jIdentifier + many space + classVarDecs <- sepBy jClassVarDec (many space) + subroutineDecs <- sepBy jSubroutineDec (many space) + many space >> char '}' + return $ JClass id classVarDecs subroutineDecs + +jSubroutineDec :: JackParser JSubroutineDec +jSubroutineDec = do + header <- jSubroutineHeader + many space + body <- jSubroutineBody + return JSubroutineDec header body + +jSubroutineBody :: JackParser JSubroutineBody +jSubroutineBody = do + char '{' >> many space + varDecs <- sepBy jVarDec (many space) + stmts <- sepBy jStatement (many space) + many space >> char '}' + return JSubroutineBody varDecs stmts |