1Compilers in Real LifeDave Mandelin2 Dec 2004Software Development Time1/6Code1/2Test1/3DesignTest1/2Code1/6Design1/3From The Mythical Man-Month by Fred BrooksCan we do more error checking and less testing?Better yet, can we avoid writing bugs in the first place?Software MaintenanceMaintenance is{Fixing bugs{Enhancing functionality{Improving performance{Refactoring 60/60 Rule{60% of project cost is maintenance{60% of maintenance is enhancements{30% of maintenance cost is reading existing code{From Facts and Fallacies of Software Engineering by Robert GlassLessons from Real Life Software needs to be{Reliable{Maintainable{Understandable{…especially if it’s any good.Solutions for Real LifeHow can we write reliable, maintainable, understandable software?Design a new language!{A language specially designed to handle yourproblem{Program is short, focused on task{“Junk” implementation details hidden And maintainable in one place{Error checking{Error avoidanceCelebrity Endorsements2Compilers are Software Programming language tools need to be maintainable, understandable too{Compilers, code analyzers, debuggers We could design special languages to help implement our languages{Too much for most projectsCan be done, though (PA3, yacc) Focus on simplicity insteadCase Study 1: Search ResultsProject SearchDepartment SearchThe Problem Many search types Want same look and feel for all{Easy to learn, use, and understand Need different result format{Different titles, linksSolution 1: Spaghetti codeif (type == PROJECT) {link1 = “project.asp?” + name;link2 = “grant.asp?” + id;} else {link1 = “dept.asp?” + id;link2 = null;}…System.out.println(link1);if (type == PROJECT) {System.out.println(link2);}Maybe it works, maybe you get firedUnmaintainableSolution 2: Write it over and over Write each search page as a separate class{Maybe Alice does departments, Bob does projects, … Hard to keep consistent look and feelSolution 3: Recipes Write each search page as a separate class{Follow a fixed recipe each time{Example: recursive descent parsingFollow a fixed recipe for each production Good strategy{But not the best!3RecipesWhat’s good about recipes?{Figure out how to do it only once{Avoid bugs if the recipe is correct What’s wrong with recipes?{Type it in many times{Can type in bugs each time{BoringA Better Way Factor out the repetition{Describe the differences with a notationPA3: grammar fileSearch: describe result format{Implement the repeated parts with interpreters, compilers, and librariesPA3: parsing engine, table generatorSearch: interpreter RFL: Result Format LanguageColumntitle=“Dept”source_data=“dept”type=STRINGlink=“dept.asp?deptid={ID}”Columntitle=“Name”source_data=”description”type=STRINGReport Format Language A configuration language for reports Syntactic sugar for the recipe code Raises level of abstraction{Java has abstraction features, toomethods, classesSometimes Java is not good enough{PA3: parsing table is unreadableNeed a new languageRFL Interpreter Search results come from database RFL program is an AST{Created programmatically – no front end Run RFL program on each result tuple340200,”Admin”340300,”Outreach”Columntitle=“Dept”source_data=“dept”type=STRINGlink=“dept.asp?deptid={ID}”Columntitle=“Name”source_data=”description”type=STRINGRFL Interpreter<tr><td><a href=…RFL Interpreter Allowed rapid development of many search pages One day, a user sends an email…{Site is slow when displaying 5000 search resultsDon’t ask{What can we do?4Running RFLInterpreterfor col in columns// Visit each columnObject data = row.getData(col.name);String s = col.format(data);if (col.hasLink()) {col.writeLink(row);}print(s);if (col.hasLink()) {print(“</a>”);}Hand-written// First columndata = row.getData(“name”);s = col.format(data);col.writeLink(row);print(s);print(“</a>”);// Second columndata = row.getData(“title”);s = col.format(data);print(s);RFL Compiler a.k.a. code generator Compile ASTs to HLL code (VBScript) Performs easy optimizations{Loop unrolling{Constant propagationEasy because compiler knows which assignments it is generating 10x speedupExpressivenessConfiguration languagesLittle languagesDomain-specific languages (DSLs)General-purpose languages (GPLs)Expressiveness,Maintenance EffortRFLVHDL, PostScript, UnrealScriptJava, Perl, Decafmake, PA2 lexer specImplementation PerformanceInterpreterBasic CompilerOptimizing CompilerFancy Optimizing CompilerExecution Speed,Development EffortRFL Interpreterjavac, RFL CompilerPA6, gccPA4UsabilityAuthorHackersProgrammersUsersUsability,Language Design Effortone-off code generatorsJava, Perl, DecafRFL, X configuration scriptsUnrealScriptEvolution of RFLConfig LanguageLittle LanguageDSLGPLInterpreter Compiler Fancy Compilerv0.001InterpreterCompiler5Case Study 2: Little Reports4,000Profit70,000Expenses14,000Deferred Revenue60,000RevenueCBL: Cash Balance Language ‘Profit’=GROUP((REV + DEF) + EXP){‘title’=GROUP(…) is CBL syntax{REVLike a primitive zero-argument functionEvaluated using a database queryWhat happens if we need values from a web site?{Need extensibility{CBL has an interface for implementing new primitives by writing a simple classError Checking in CBLDebits and credits are confusing{Which is right, REV – DEF or REV + DEF?{“That’s like asking the square root of million. No one will ever know.” – Nelson Muntz A type system{Two types: UP and DOWN{Same types must add, different types must subtract{Can check this statically{Is there a better way?Error Avoidance in CBL Just type REV ± DEF CBL figures out the right operation Program is underconstrained Language implementation uses inference to select operationsCBL Implementation Like PA1-PA3, but simpler{Hand-written DFA lexerI didn’t have a lexer generator{Hand-written recursive descent parserWorks well for little languages{InterpreterOperation inferenceExpression evaluatorExtension interfaceCBL In Practice I developed it in a few days{It was easy after PA1-PA3 Gave the code to another CS 164 graduate, who{Added some new features{Started writing programs Users ask for a new report{It’s done in 60 seconds6CBL Evaluation Much better than RFL Text-based language Error avoidance
View Full Document