Parsing Types: Converting Type Languages, Study notes of Computer Science

A lecture on parsing types in programming languages, focusing on converting types from one language to another. The lecture covers the basics of parsing, including the definition of a parser and the use of operators like return and (>>=). The main goal is to create a parser for transforming types in a source language to a target language, which involves defining a typ parser and handling efficient parsing. The document also discusses the importance of parsing types in compilers and the need to associate compound types to the right.

Typology: Study notes

Pre 2010

Uploaded on 08/19/2009

koofers-user-jed
koofers-user-jed 🇺🇸

10 documents

1 / 7

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Lecture 27
Lectured and scribed by Sunil Kothari
December 12, 2008
1 Overview
Our goal today is to have parsers which transform types in one language to
another language. Specifically, we want ”(a(bc))” to be converted into
”(Arrow (T yV ar a)(Arrow (T yV ar b)(T yV ar c)))”.
We plan to do the following:
1. We will start with a simple type language which requires parens for unique
parse trees.
2. We will look at an efficient version of the above parser.
3. Next, we look at how to parse without parens.
4. Finally, we make the parens optional in our language.
2 Review
Recall that parser type is defined as:
newT ype P arser a =M kP (String [(a, S tring)])
In the previous lecture, we looked at the different ways of defining a type. Look
at the notes or in the book, if you want more information.
For all the parsers that we define in this lecture, most of them can be made
from only two operators. return is defined as:
return :: a -> Parser a
return v = MkP( i -> [(v,i)])
Parser1> apply (return 1) "abc"
[(1,"abc")] :: [(Integer,String)]
The other operator is (>>=), called ”then” in Hutton’s book.
1
pf3
pf4
pf5

Partial preview of the text

Download Parsing Types: Converting Type Languages and more Study notes Computer Science in PDF only on Docsity!

Lecture 27

Lectured and scribed by Sunil Kothari

December 12, 2008

1 Overview

Our goal today is to have parsers which transform types in one language to another language. Specifically, we want ”(a → (b → c))” to be converted into ”(Arrow (T yV ar a)(Arrow (T yV ar b)(T yV ar c)))”. We plan to do the following:

  1. We will start with a simple type language which requires parens for unique parse trees.
  2. We will look at an efficient version of the above parser.
  3. Next, we look at how to parse without parens.
  4. Finally, we make the parens optional in our language.

2 Review

Recall that parser type is defined as:

newT ype P arser a = M kP (String → [(a, String)])

In the previous lecture, we looked at the different ways of defining a type. Look at the notes or in the book, if you want more information. For all the parsers that we define in this lecture, most of them can be made from only two operators. return is defined as:

return :: a -> Parser a return v = MkP( i -> [(v,i)])

Parser1> apply (return 1) "abc" [(1,"abc")] :: [(Integer,String)]

The other operator is (>>=), called ”then” in Hutton’s book.

p >>= f MkP (\i -> case (apply p i) of [] -> [] [(v,out)] -> apply (f v) out

In general, parsers are built in the following fashion p 1 >>= λv 1 → p 2 >>= λv 2 → .. . pn >>= λvn → return (f v 1 v 2... vn) This notation is normally not used. Instead Haskell provides the do notation

do v 1 ← p 1 v 2 ← p 2 .. . v 3 ← pn return f v 1 v 2... vn

Let’s briefly review some of the parsers that Prof. Caldwell introduced last time.

item, which parses a string character by character

item:: Parser Char item = MkP(ı -> case i of [] -> [] (x:xs) -> [(x,xs)])

Next, we define a parser which reads the first three characters of a string and returns a pair of the first and the third character, and also returns the remaining string.

p :: Parser (Char,Char)

p = do x <- item item y <- item return (x,y)

Parser> apply p "xyzzy" [((’x’,’z’),"zy")] :: [((Char,Char),String)]

The two parsers can also be combined using the +++ (choice) operator.

typ::Parser Type typ = tyvar +++ arrow +++ prod

The typ parser is a ”choice” in the sense that we can either have a type variable or an arrow type or a product type. The tyvar, arrow, and prod parsers are defined as:

tyvar:: Parser Type tyvar = do n <- identifier return (TyVar n)

arrow::Parser Type arrow = do symbol "(" a <- typ symbol "-" symbol ">" b <- typ symbol ")" return (Arrow a b)

prod:: Parser Type prod = do symbol "(" a <- typ symbol "x" b <- typ symbol ")" return (Prod a b)

We can load this and check.

Parser1> apply typ "(a -> (b -> c))" [(Arrow (TyVar "a") (Arrow (TyVar "b") (TyVar "c")),[])] :: [(Type,String)] Parser1> apply typ "(a -> b -> c))" [] :: [(Type,String)] Parser1> apply typ "(a -> b -> c)" [] :: [(Type,String)] Parser1> apply typ "(a -> b) -> c" [(Arrow (TyVar "a") (TyVar "b"),"-> c")] :: [(Type,String)]

Note that we the parser takes care of extra spaces as shown below:

Parser1> apply typ "((a -> b ) -> c)" [(Arrow (Arrow (TyVar "a") (TyVar "b")) (TyVar "c"),[])] :: [(Type,String)] Parser1>

The parser so created is not an efficient parser. The inefficiency comes from the following code:

typ::Parser Type typ = tyvar +++ arrow +++ prod

To have an efficient parser, we change the code slightly. The new parser is:

typ::Parser Type typ = tyvar +++ comptype

comptype ::Parser Type comptype = do symbol "(" a <- typ constructor <- op c <- typ symbol ")" return (constructor a c)

op:: Parser (Type -> Type -> Type) op = arrow +++ prod

arrow ::Parser (Type -> Type -> Type) arrow = do symbol "->" return Arrow

prod::Parser (Type -> Type -> Type) prod = do symbol "x" return Prod

This doesn’t change the final output. For example,

Parser2> apply typ "((a -> b ) -> c)" [(Arrow (Arrow (TyVar "a") (TyVar "b")) (TyVar "c"),[])] :: [(Type,String)] Parser2>

Now we switch to a type language, where the compound types always asso- ciate to the right. So we can do away with the parens in our source language. The new grammar is given as:

type ::= string | type ” → ” type | type ” × ” type

The parser undergoes a slight modification.

[(Arrow (TyVar "a") (Arrow (Arrow (TyVar "b") (TyVar "c")) (Arrow (TyVar "d") (TyVar "e") Parser4> apply typ "a -> (b -> c -> d) -> e" [(Arrow (TyVar "a") (Arrow (Arrow (TyVar "b") (Arrow (TyVar "c") (TyVar "d"))) (TyVar "e" Parser4>