==== 2021-Mar-30 - hw07 soln - Y0 examples of syntax internal representation implementation of eval, toString Let's represent parse-trees for Y0 internally: ; an Expr is: ; - a number, OR ; - (make-paren [Expr]) ; - (make-binop [Op] [Expr] [Expr]), OR ; - (make-if-zero [Expr] [Expr] [Expr]) ; An Op is: one-of "blam","swish","splat" ; examples of the data 8 (make-paren 8) (make-binop "blam" 2 8) (make-if-zero 8 17 2) (check-expect (parse "{= < swish 5> =}") (make-paren (make-binop "swish" (make-binop "blam" 2 8)) 5)) (check-expect (expr->string (make-paren (make-binop "swish" (make-binop "blam" 2 8)) 5)) "{= < swish 5> =}") (make-paren (make-paren (make-paren (make-paren 8))) [paste this into DrRacket; see: Y0-start.rkt] ==== 2021-Mar-16 S ⇒ N V N . (rule #1b) ⇒ N V android . (rule #2g) ⇒ hotdog V android . (rule #2f) ⇒ hotdog hit android . (rule #3d) A very-slightly-better-grammar 1a. “S” can be replaced with “NP V .” 1b. “S” can be replaced with “NP V NP .” 2a-h. “N” can be replaced with “cat” or “ufo” or “apple” or “fox” or “dog” or “hotdog” or “android” or “itec” 3a-g. “V” can be replaced with with “bite” or “run” or “jump” or “hit” or “love” or “spin” or “hear” 4. "NP" can be replaced with "ART N" 5a-c. "ART" can be replace with "a" or "an" or "the" Goal: turn "S" into "the hotdog hit an android ." S => NP V NP . (rule #1b) => NP V ART N . (rule #4) => NP V an N . (rule #5b) => NP V an android . (rule #2g) => ART N V an android . (rule #4) => the N V an android . (rule #5c) => the hotdog V an android . (rule #2f) => the hotdog hit an android . (rule #3d) == a grammar for java-field-declaration examples: int n; double x = 3.14; private String myStuff = "mississippi".substring(2,2+4); private String myStuff = bestUSState; private static String myStuff = "mississippi".substring(2,2+4); FieldDecl -> VisibilityModifier Type Id InitializerOpt ; InitializerOpt -> Initializer | ε Initializer -> = Expression VisibilityModifier -> public | ε | private | protected “ε” means the-empty-string -- used because otherwise it's hard to see in grammars! Type -> PrimType | Id PrimType -> byte | short | int | long | float | double | boolean | char Number -> ... Expr -> LiteralValue | Id | FunctionCall | ...??? LiteralValue -> Number | StringLiteral | BooleanLiteral | CharLiteral Id -> ...??? ==== 2021-Mar-18 Give a grammar for: - racket `define` Take 1: Defn -> ( define Function ) Function -> ( Id Value Value ) Function -> ( Id Value ) Id -> ... Value -> ... Defn ⇒ ( define Function ) ⇒ ( define (Id Value Value) ) ⇒* ( define (myFunc Value Value) ) ⇒* ( define (myFunc 7 "hello") ) Take 2: Examples of the data: (define SHIP-DX +5) (define MAX-W (image-width BLACKNESS)) (define MAX-W MAX-H) (define (move-ship a-s) (+ 8 pi)) Defn -> ( define Id Expr ) Defn -> ( define (Id Id) Expr ) ;a function of one variable Test-case: Derivation of: (define (move-ship a-s) (+ 8 pi)) Defn ⇒ (define (Id Id) Expr) ⇒* (define (move-ship Id) Expr) ⇒* (define (move-ship a-s) Expr) ⇒* (define (move-ship a-s) (+ 8 pi)) ⇒ (define (move-ship a-s) (+ 8 pi)) Id -> ... Expr -> ... Value -> ... == Let's make a grammar for Java Identifiers: Id -> Letter LettersOrDigits (rule 1) LettersOrDigits -> ε | LetterOrDigit LettersOrDigits (rule 2a,2b) LetterOrDigit -> Letter | Digit (rule 3a,3b) Letter -> a|b|c|…|z|_ (rule 4a..4z,4_) Digit -> 0|1|2|…|9 (rule 5a..5j) Id -> Letter LettersOrDigits (rule 1) -> f LettersOrDigits (rule 4f) -> f LetterOrDigit LettersOrDigits (rule 2b) -> f Letter LettersOrDigits (rule 3a) -> f u LettersOrDigits (rule 4u) -> f u LettersOrDigits LettersOrDigits -> f u n LettersOrDigits -> f u n LetterOrDigit LetterOrDigits -> f u n 9 LetterOrDigits -> f u n 9 ε = fun9 == grammar for a Java Class declaration: ClassDecl -> VisModifierOpt class ExtendsClauseOpt Id { FieldDeclOrMethodDeclOrClassDecls } FieldDeclOrMethodDeclOrClassDecls -> ε | FieldDeclOrMethodDeclOrClassDecl FieldDeclOrMethodDeclOrClassDecls FieldDeclOrMethodDeclOrClassDecl -> FieldDecl | MethodDecl | ClassDecl ... == exercise: write a grammar for racket's "let" expression. or, racket's "cond" expression. Def'n: a grammar is *ambiguous* if one string has two different parse trees. Example: simple arithmetic-expressions: such as 27 2 + 3 2 + ((3)) 2 + 3 + 4 3*4+2 (3*4)+2 3*(4+2) 3*4+2-3*5 (3*4+2-3*5) ArithExpr -> Number | ArithExpr Op ArithExpr | ( ArithExpr ) Op -> + | - | * | / 3*4+2 has two different derivations. (the op "*" close to root, or "+" close to root) Thus this grammar is ambiguous. In grade school, we learned *EXTRA* rules about precedence, to choose which of these parse trees is the "right" one. We have two solutions to ambiguity: - add ADDITIONAL rules (outside the grammar) for choosing precedence - make our grammar more complicated, to only allow ONE of the trees to be created. 2*3+4 (+ (* 2 3) 4) (* 2 (+ 3 4)) - racket function-application .... of 2 arguments (e.g. `expt` or `cons` or `min`) FuncApply => ( Id Expr Expr ) Derivation of: - Java identifiers - racket `define-struct` ==== 2017-Sep-30 1a FieldDecl → Modifier Type Id ; 1b FieldDecl → Modifier Type Id = Expr ; 2 Modifier → public | private | protected | ε | synchronized | ... ; FieldDecl ⇒ Modifier Type Id ; rule 1a ⇒ Type Id; rule 2d ⇒ int Id; ...by not-shown-here rules for `Type` ⇒ int n; ...by not-shown-here rules for `Id` FieldDecl ⇒ Modifier Type Id = Expr ; rule 1b ⇒ private Type Id = Expr ; rule 2b ⇒ private String Id = Expr ; ...by not-shown-here rules for `Type` ⇒ private String myStuff = Expr ; ...by not-shown-here rules for `Id` ⇒ private String myStuff = "mississippi".substring(2,2+4); ...by not-shown-here rules for `Expr`