43 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			43 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| Chapter 5, challenge 1:
 | |
| Earlier, I said that the | , * , and + forms we added to our grammar metasyntax
 | |
| were just syntactic sugar. Take this grammar:
 | |
| 
 | |
| expr → expr ( "(" ( expr ( "," expr )* )? ")" | "." IDENTIFIER )+
 | |
| 	| IDENTIFIER
 | |
| 	| NUMBER
 | |
| 
 | |
| Produce a grammar that matches the same language but does not use any of the notational sugar.
 | |
| 
 | |
| solution:
 | |
| expr -> IDENTIFIER
 | |
| expr -> NUMBER
 | |
| expr -> expr callOrIndex
 | |
| 
 | |
| callOrIndex -> "." IDENTIFIER
 | |
| callOrIndex -> "(" call ")"
 | |
| 
 | |
| call ->
 | |
| call -> expr
 | |
| call -> expr callListEnd
 | |
| 
 | |
| callListEnd -> 
 | |
| callListEnd -> "," expr precedingCommaCall
 | |
| 
 | |
| 
 | |
| The grammar here clearly describes a number, or an identifier to a number, or a
 | |
| function call, or a structure access
 | |
| 
 | |
| Chapter 5, challenge 2:
 | |
| The Visitor pattern lets you emulate the functional style in an object-oriented
 | |
| language. Devise a complementary pattern for a functional language. It should let
 | |
| you bundle all of the operations on one type together and let you define new types
 | |
| easily.
 | |
| (SML or Haskell would be ideal for this exercise, but Scheme or another Lisp works
 | |
| as well.)
 | |
| 
 | |
| solution:
 | |
| Here, we're supposed to be able to define a new type that "inherits" an
 | |
| existing one and bundle all the function implementations on that type together.
 | |
| We could simply write the functions by specific type in one place, since Haskell is just that flexible, but that doesn't guarrantee we wrote the needed functions.
 | |
| Another thing we could do is to put all necessary functions in a single structure, and define a type for this structure, for example if our supertype is Expr, with functions like "printInStr", "execute" and "optimize", our function bundle would look like:
 | |
| data ExprFuncs a = ExprFuncs (a -> str) (a -> IO ()) (a -> Expr)
 | 
