; This program implements and tests a recursive descent parser for a ; language defined by a grammar given below. The function "parse" ; takes as its argument the name of a text file. It attempts to ; parse the text as a program in the language generated by the grammar. ; If the parse is successful, a representation of a parse tree is ; returned. Otherwise an error message is printed, and #f is returned. ; The function "traverse" simply prints the tree if there is one (i.e., ; if its input is not #f). Otherwise it prints an error message. ; The function "yield" returns a list of the tokens in the leaves of ; a parse tree (from left to right). This should be the list of ; tokens in the string that was parsed. ; The "main" function simply tests the functions by calling it with ; a number of different text files. Each file is expected to be in ; the current directory. ; The grammar for the language is given below. Here nonterminals are ; capitalized. The grammar has been expanded so that in each rule, ; only tokens appear on the RHS of the arrow. ; The start symbol is "Conditional". ; Conditional -> ShortIf RestIf ; ShortIf -> if Test then Block ; RestIf -> else Block endif ; RestIf -> endif ; Test -> < Var Op Var> ; Var -> x ; Var -> y ; Var -> z ; Op -> = ; Op -> /= ; Block -> begin RestBlock ; RestBlock -> end ; RestBlock -> Statement Statements ; Statements -> end ; Statements -> Statement Statements ; Statement -> Var := Var ;;;;;;;;;;;;;;;;; The "main" function ;;;;;;;;;;;;;;;;;;;;;;;;;; (define (main) (traverse (parse "data1.txt")) (newline) (newline) (display (yield (parse "data1.txt"))) (newline) (newline) (traverse (parse "data2.txt")) (newline) (newline) (display (yield (parse "data2.txt"))) (newline) (newline) (traverse (parse "data3.txt")) (newline) (newline) (display (yield (parse "data3.txt"))) (newline) (newline) (traverse (parse "data4.txt")) (newline) (newline) (display (yield (parse "data4.txt"))) (newline) (newline) (traverse (parse "data5.txt")) (newline) (newline) (display (yield (parse "data5.txt"))) (newline) (newline) (traverse (parse "data6.txt")) (newline) (newline) (display (yield (parse "data6.txt"))) (newline) (newline) (traverse (parse "data7.txt")) (newline) (newline) (display (yield (parse "data7.txt"))) (newline) (newline) (traverse (parse "data8.txt")) (newline) (newline) (display (yield (parse "data8.txt"))) (newline) (newline) (traverse (parse "data9.txt")) (newline) (newline) (display (yield (parse "data9.txt"))) (newline) (newline) (traverse (parse "data10.txt")) (newline) (newline) (display (yield (parse "data10.txt"))) (newline) (newline) (traverse (parse "data11.txt")) (newline) (newline) (display (yield (parse "data11.txt"))) (newline) (newline) (traverse (parse "data12.txt")) (newline) (newline) (display (yield (parse "data12.txt"))) (newline) (newline) (traverse (parse "data13.txt")) (newline) (newline) (display (yield (parse "data13.txt"))) (newline) (newline) (traverse (parse "data14.txt")) (newline) (newline) (display (yield (parse "data14.txt"))) (newline) (newline) (traverse (parse "data15.txt")) (newline) (newline) (display (yield (parse "data15.txt"))) (newline) (newline) (traverse (parse "data16.txt")) (newline) (newline) (display (yield (parse "data16.txt"))) (newline) (newline) (traverse (parse "data17.txt")) (newline) (newline) (display (yield (parse "data17.txt"))) (newline) (newline) )