SlideShare ist ein Scribd-Unternehmen logo
1 von 50
Downloaden Sie, um offline zu lesen
Providing Rapid Feedback in
 Generated Modular Language
        Environments


Lennart Kats (me)
Maartje de Jonge
Emma Nilsson-Nyman
Eelco Visser

OOPSLA 2009                           October 29, 2009



Software Engineering Research Group
Domain-Specific Languages


• Encapsulate domain knowledge

• Eliminate boilerplate code

• Domain-specific analysis / verification /
  optimization
Integration and Composition of DSLs




            Data                       Access      Data
Workflow             UI     Actions
           models                      control   validation


                                HQL


                    (www.webdsl.org)
DSLs without IDE support
                          are a nonstarter!




Markus Voelter [Practical Product Lines 2009]
Spoofax/IMP:
Efficient Editor Development


• Existing platform: Eclipse with IMP

• DSLs to define editor components

• Grammar and a parser generator:
  SDF, (J)SGLR
Code Folding                                               Outline




                                                                                Brace matching
HQL                                                                                                             

                           Semantic errors                                           References
                                                 FOLDING/OUTLINE




entity User {
  ...
}

entity BlogPost {
  poster : User                       REFERENCE
  body   : String
}
What about
     incorrect and incomplete programs?


entity User {
                                                   NORMAL PARSING
     name                  : String
     password : String
     homepage
}

entity BlogPost {
  poster : User
  body   : String
}
What about
       incorrect and incomplete programs?


 entity User {
      name                 : String
                                                   NORMAL PARSING
      password : String
      homepage
                                                                          ERROR
 }

 entity BlogPost {                                              Parse failure:
      poster : User                                             No abstract syntax tree
      body             : String
 }
                                                           NEVER PARSED
Mini-Demo




    Error Recovery in
a data modeling language
Parsing with SDF and SGLR

• Language composition without
  shift/reduce conflicts

• Ambiguities can be inspected

• Declarative disambiguation
Normal LR Parser
token   token   token   token         token        x
                                   Recovery:
                                 Backtracking,
                            skip/insert tokens, etc.

(S)GLR Parser
                token   x
token   token   token   token         token        x
                                      token        x

                                 Recovery: ?
Do we really need to dive into this
    intimidating algorithm?
Island Grammars                                  [Van Deursen & Kuipers, 1999]

• Parse only interesting bits (Islands)
• Skip the remaining characters (Water)


   IDENTIFICATION DIVISION.
   PROGRAM-ID. EXAMPLE.
                                                                                          WATER
   PROCEDURE DIVISION.
        CALL X.
        YADA.
                                                                                          WATER
        YADA YADA.
        CALL Y.
                                                             Grammar-based
                                                             “error recovery”!
Island Grammars      [Van Deursen & Kuipers, 1999]




       ~[ tn]+ → WATER {avoid}
Running Example: Java
Error Recovery Recipe
1. Take the entire Java grammar
2. Add water
3. Mix it together
Mixing Java with Water
public class TemperatureMonitor {
  private Fridge fridge;

    public void trigger(Temperature temp) {
      if (temp.greaterThan(MAX)) // missing {
        fridge.startCooling();                     ERROR
      }
      return;
    }

    public TemperatureMonitor(Fridge fridge) {
      this.fridge = fridge;
    }
}
Mixing Java with Water
 public class TemperatureMonitor {
      private Fridge fridge;
                                                                        NORMAL PARSING
    public void trigger(Temperature temp) {
      if (temp.greaterThan(MAX)) // missing {
        fridge.startCooling();                     ERROR
      }
      return;
    }

    public TemperatureMonitor(Fridge fridge) {
      this.fridge = fridge;
    }
}
Mixing Java with Water
 public class TemperatureMonitor {
   private Fridge fridge;

      public void trigger(Temperature temp) {
           if (temp.greaterThan(MAX)) // missing {
                fridge.startCooling();                                                      ERROR
                                                                         NORMAL PARSING
      } }
           return;
      }

     public TemperatureMonitor(Fridge fridge) {
       this.fridge = fridge;
     }
 }
Mixing Java with Water
 public class TemperatureMonitor {
   private Fridge fridge;

      public void trigger(Temperature temp) {
           if (temp.greaterThan(MAX)) // missing {
                fridge.startCooling();                                                      ERROR
                                                                         NORMAL PARSING
      } }
           return;
                                                            UNEXPECTED KEYWORD
      }

     public TemperatureMonitor(Fridge fridge) {
       this.fridge = fridge;
     }
 }
Mixing Java with Water
public class TemperatureMonitor {
  private Fridge fridge;

 public void trigger(Temperature temp) {
   if (temp.greaterThan(MAX)) // missing {
     fridge.startCooling();
   }
   return;
 }

  public TemperatureMonitor(Fridge fridge) {
    this.fridge = fridge;
  }
} New production:
    WATER → MethodDec {cons(“WATER”)}
                      {cons(“WATER”),recover}
Mixing Java with Water
public class TemperatureMonitor {
  private Fridge fridge;

 public void trigger(Temperature temp) {
      if (temp.greaterThan(MAX)) // missing {
           fridge.startCooling();
      }
      return;
                                                                                          WATER
 }

  public TemperatureMonitor(Fridge fridge) {
    this.fridge = fridge;
  }
} New production:
    WATER → MethodDec {cons(“WATER”),recover}
              Stm {cons(“WATER”),recover}
Mixing Java with Water
public class TemperatureMonitor {
  private Fridge fridge;

 public void trigger(Temperature temp) {
   if (temp.greaterThan(MAX)) // missing {
        fridge.startCooling();
   }
                                                                                       WATER
   return;
 }

  public TemperatureMonitor(Fridge fridge) {
    this.fridge = fridge;
  }
} New production:
    WATER → Stm {cons(“WATER”),recover}
Mixing Java with Water
public class TemperatureMonitor {
  private Fridge fridge;

    public void trigger(Temperature temp) {
      if (temp.greaterThan(MAX)) // missing {
           fridge.startCooling();                                                       LAYOUT
      }
                                                                                          WATER
           PROBLEMATIC TOKEN
      return;
    }

    public TemperatureMonitor(Fridge fridge) {
      this.fridge = fridge;
    }
}
Mixing Java with Water
public class TemperatureMonitor {
  private Fridge fridge;

 public void trigger(Temperature temp) {
   if (temp.greaterThan(MAX)) // missing {
        fridge.startCooling();                                                       LAYOUT
   }
                                                                                       WATER
        PROBLEMATIC TOKEN
   return;
 }

  public TemperatureMonitor(Fridge fridge) {
    this.fridge = fridge;
  }
} New production:
    WATER → LAYOUT {cons(“WATER”),recover}
Mixing Java with Water
public class TemperatureMonitor {
  private Fridge fridge;

 public void trigger(Temperature temp) {
   if (temp.greaterThan(MAX)) // missing {
       fridge.startCooling();                  LAYOUT
   }
        WATER
   return;
 }

  public TemperatureMonitor(Fridge fridge) {
    this.fridge = fridge;
  }
} New production:
    WATER → LAYOUT {cons(“WATER”),recover}
Reflection:
Water-based Recovery Rules

•
• Works with any existing grammar

• Can only remove fragments
Danger of Floods
public class Fridge {
  public void startCooling() {
    cooling.commence();
  // missing }

    public void onResetButtonPress() {
      log.message(“Reset button pressed”);
      power.reboot();
    }
}
Danger of Floods
public class Fridge {
  public void startCooling() {
    cooling.commence();
  // missing }

    public void onResetButtonPress() {
                                                                                                WATER
         log.message(“Reset button pressed”);
         power.reboot();
    }
}


                          So why not parse methods
                         with missing closing brackets?
Productions for Missing Literals

 why not add rules like this:


“if” “(” Expr          Stm → Stm {cons(“If”), recover}


 and this, and this, and this:

“if”    Expr “)” Stm → Stm {cons(“If”), recover}
“if”    Expr     Stm → Stm {cons(“If”), recover}
“while” “(“ Expr Stm → Stm {cons(“While”), ...}
...

 not going to scale.
Productions for Missing Literals


“if” “(” Expr “)” Stm → Stm {cons(“If”)}

 what it means internally:
IF BOPEN … BCLOSE … → …
[i][f]                               → IF
[(]                                   → BOPEN
[)]                                   → BCLOSE
  so, we can write (using the literal instead of BCLOSE):

                             → BCLOSE {recover}
                                “)”
                             → “}”    {recover}
Applying Insertion Rules
public class Fridge {
  public void startCooling() {
    cooling.commence();
  // missing }

    public void onResetButtonPress() {
      log.message(“Reset button pressed”);
      power.reboot();
    }
}

     New production:
           → “}” {recover}
Applying Insertion Rules
public class Fridge {
  public void startCooling() {
       cooling.commence();
  // missing }
                                                                     INSERT }

    public void onResetButtonPress() {
      log.message(“Reset button pressed”);
      power.reboot();
    }
}

     New production:
           → “}” {recover}
Recovery Rules
•
    •   Water
    •                              So who's gonna
    •   Closing brackets   (“}”)    write all those
                                   recovery rules?
    •
    •   Opening brackets (“{”)
    •
    •   Separators         (“,”)
    •                                We derive
                                   them from the
    •   Comments
                                     grammar!
    •
    •   String literals
Customization of Recovery Rules


        → “class” {reject}

   “[|” → “|[“ {recover}

   “|]” → “]|” {recover}
Putting Things Together

 • Water              y = f ( x   + 1   ;
 • Insertion: “)”     y = f ( x   + 1 ) ;
y =     x         ;   y = f ( x ) + 1   ;
    f ( x   + 1 ) ;   y = f       + 1   ;
    f (       1 ) ;   y = f (       1 ) ;
y     ( x   + 1 ) ;   y =   ( x ) + 1   ;
y     ( x )       ;   y =   ( x   + 1 ) ;
y     ()          ;   y =     x   + 1   ;
y     (       1 ) ;   y = f             ;
y =           1   ;   y =   ( x )       ;
                  ;   y = f ( )         ;
Putting Things Together




  For recovery, parallel parsing does not scale...
Putting Things Together




    Why not do backtracking for recovery?
Recovery Using Backtracking
public class TemperatureMonitor {
  private Fridge fridge;

    public void trigger(Temperature temp) {
      if (temp.greaterThan(MAX)) // missing {
        fridge.startCooling();                     ERROR
      }
      return;
    }

    public TemperatureMonitor(Fridge fridge) {
      this.fridge = fridge;
    }
}
Recovery Using Backtracking
public class TemperatureMonitor {
     private Fridge fridge;
                                                                   1. NORMAL PARSING
    public void trigger(Temperature temp) {
      if (temp.greaterThan(MAX)) // missing {
        fridge.startCooling();                     ERROR
      }
      return;
    }

    public TemperatureMonitor(Fridge fridge) {
      this.fridge = fridge;
    }
}
Recovery Using Backtracking
public class TemperatureMonitor {
  private Fridge fridge;

      public void trigger(Temperature temp) {
           if (temp.greaterThan(MAX)) // missing {
               fridge.startCooling();                                                     ERROR
                                                                    1. NORMAL PARSING
           }
           return;
                                                                  POINT OF DETECTION
      }

     public TemperatureMonitor(Fridge fridge) {
       this.fridge = fridge;
     }
}
Recovery Using Backtracking
public class TemperatureMonitor {
  private Fridge fridge;

      public void trigger(Temperature temp) {
           if (temp.greaterThan(MAX)) // missing {
               fridge.startCooling();
                                                                    1. NORMAL PARSING
           }
           return;
                                                                       2. BACKTRACKING
      }

    public TemperatureMonitor(Fridge fridge) {
      this.fridge = fridge;
    }
}
Recovery Using Backtracking
public class TemperatureMonitor {
  private Fridge fridge;

    public void trigger(Temperature temp) {
      if (temp.greaterThan(MAX)) { missing {
                                                                                    
                                                      //              1 RULE
        fridge.startCooling();                                      2 RULES
                                                                      1 RULE
                                                                                    
      }                                                             3 RULES
                                                                    2 RULES
                                                                      1 RULE
                                                                                    
      return;                                                                       
                                                                    4 RULES
                                                                    3 RULES
                                                                    2 RULES
                                                                      1 RULE
    }

    public TemperatureMonitor(Fridge fridge) {
      this.fridge = fridge;
    }
}
Evaluation
 Implementation:
  • JSGLR
  • Spoofax/IMP (WebDSL, Stratego, PIL, ...)

 Test grammars:
  • Java
  • Java-SQL
  • Stratego
  • Stratego-Java
Evaluation

 Measurements:
  • qualitative [Penello & DeRemer '78]:
      excellent / good / poor
  • tree alignment distance [Jian et al '94]
  • textual 'diffs'
Recovery Quality (Stratego-Java)
Continued Work

 “Natural and Flexible Error Recovery
  for Generated Parsers” [SLE 2009]
  • indentation-based region selection
  • fall-back mechanism
  • bridge parsing [Nilsson-Nyman et al, 2008]




     (www.strategoxt.org/Stratego/PermissiveGrammars)
Continued Work

 “Natural and Flexible Error Recovery
  for Generated Parsers” [SLE 2009]
  • comparison with JDT
  • performance, quality
  • synergy between recovery techniques




     (www.strategoxt.org/Stratego/PermissiveGrammars)
Conclusion
       SGLR/SDF
        • modular specifications
        • composable languages

       Recovery production rules
        • transparent
        • flexible
        • language-independent

www.strategoxt.org/Stratego/PermissiveGrammars
www.strategoxt.org/Stratego/Spoofax­IMP
www.lennartkats.net



   Software Engineering Research Group

Weitere ähnliche Inhalte

Ähnlich wie Providing Rapid Feedback in Generated Modular Language Environments (OOPSLA 2009)

Testing Cassandra Guarantees under Diverse Failure Modes with Jepsen
Testing Cassandra Guarantees under Diverse Failure Modes with JepsenTesting Cassandra Guarantees under Diverse Failure Modes with Jepsen
Testing Cassandra Guarantees under Diverse Failure Modes with Jepsen
jkni
 
[Strukelj] Why will Java 7.0 be so cool
[Strukelj] Why will Java 7.0 be so cool[Strukelj] Why will Java 7.0 be so cool
[Strukelj] Why will Java 7.0 be so cool
javablend
 
Intro to scala
Intro to scalaIntro to scala
Intro to scala
Joe Zulli
 
A Discussion on Automatic Programming
A Discussion on Automatic ProgrammingA Discussion on Automatic Programming
A Discussion on Automatic Programming
techmonkey4u
 
SOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principlesSOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principles
Sergey Karpushin
 

Ähnlich wie Providing Rapid Feedback in Generated Modular Language Environments (OOPSLA 2009) (20)

Beyond java8
Beyond java8Beyond java8
Beyond java8
 
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
 
DataStax: Testing Cassandra Guarantees Under Diverse Failure Modes With Jepsen
DataStax: Testing Cassandra Guarantees Under Diverse Failure Modes With JepsenDataStax: Testing Cassandra Guarantees Under Diverse Failure Modes With Jepsen
DataStax: Testing Cassandra Guarantees Under Diverse Failure Modes With Jepsen
 
Testing Cassandra Guarantees under Diverse Failure Modes with Jepsen
Testing Cassandra Guarantees under Diverse Failure Modes with JepsenTesting Cassandra Guarantees under Diverse Failure Modes with Jepsen
Testing Cassandra Guarantees under Diverse Failure Modes with Jepsen
 
Sparkling Water Meetup
Sparkling Water MeetupSparkling Water Meetup
Sparkling Water Meetup
 
Kotlin - Better Java
Kotlin - Better JavaKotlin - Better Java
Kotlin - Better Java
 
[Strukelj] Why will Java 7.0 be so cool
[Strukelj] Why will Java 7.0 be so cool[Strukelj] Why will Java 7.0 be so cool
[Strukelj] Why will Java 7.0 be so cool
 
Ceylon - the language and its tools
Ceylon - the language and its toolsCeylon - the language and its tools
Ceylon - the language and its tools
 
Intro to scala
Intro to scalaIntro to scala
Intro to scala
 
Writing code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen Luong
 
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
TechkTalk #12 Grokking: Writing code that writes code – Nguyen LuongTechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
 
Java script for web developer
Java script for web developerJava script for web developer
Java script for web developer
 
A Discussion on Automatic Programming
A Discussion on Automatic ProgrammingA Discussion on Automatic Programming
A Discussion on Automatic Programming
 
Decompiling Java - SCAM2009 Presentation
Decompiling Java - SCAM2009 PresentationDecompiling Java - SCAM2009 Presentation
Decompiling Java - SCAM2009 Presentation
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloaded
 
SOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principlesSOLID, DRY, SLAP design principles
SOLID, DRY, SLAP design principles
 
Workshop Scala
Workshop ScalaWorkshop Scala
Workshop Scala
 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....
 
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConfPatterns for JVM languages JokerConf
Patterns for JVM languages JokerConf
 
The Great Scala Makeover
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala Makeover
 

Mehr von lennartkats

Integrated Language Definition Testing: Enabling Test-Driven Language Develop...
Integrated Language Definition Testing: Enabling Test-Driven Language Develop...Integrated Language Definition Testing: Enabling Test-Driven Language Develop...
Integrated Language Definition Testing: Enabling Test-Driven Language Develop...
lennartkats
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
lennartkats
 

Mehr von lennartkats (6)

Docker at Cloud9 IDE
Docker at Cloud9 IDEDocker at Cloud9 IDE
Docker at Cloud9 IDE
 
Remix Your Language Tooling (JSConf.eu 2012)
Remix Your Language Tooling (JSConf.eu 2012)Remix Your Language Tooling (JSConf.eu 2012)
Remix Your Language Tooling (JSConf.eu 2012)
 
Integrated Language Definition Testing: Enabling Test-Driven Language Develop...
Integrated Language Definition Testing: Enabling Test-Driven Language Develop...Integrated Language Definition Testing: Enabling Test-Driven Language Develop...
Integrated Language Definition Testing: Enabling Test-Driven Language Develop...
 
Decorated Attribute Grammars (CC 2009)
Decorated Attribute Grammars (CC 2009)Decorated Attribute Grammars (CC 2009)
Decorated Attribute Grammars (CC 2009)
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
 
Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...
Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...
Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...
 

Kürzlich hochgeladen

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Kürzlich hochgeladen (20)

AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 

Providing Rapid Feedback in Generated Modular Language Environments (OOPSLA 2009)

  • 1. Providing Rapid Feedback in Generated Modular Language Environments Lennart Kats (me) Maartje de Jonge Emma Nilsson-Nyman Eelco Visser OOPSLA 2009 October 29, 2009 Software Engineering Research Group
  • 2. Domain-Specific Languages • Encapsulate domain knowledge • Eliminate boilerplate code • Domain-specific analysis / verification / optimization
  • 3. Integration and Composition of DSLs Data Access Data Workflow UI Actions models control validation HQL (www.webdsl.org)
  • 4. DSLs without IDE support are a nonstarter! Markus Voelter [Practical Product Lines 2009]
  • 5. Spoofax/IMP: Efficient Editor Development • Existing platform: Eclipse with IMP • DSLs to define editor components • Grammar and a parser generator: SDF, (J)SGLR
  • 6. Code Folding Outline Brace matching HQL                                                                                                              Semantic errors References
  • 8. What about incorrect and incomplete programs? entity User {                                                    NORMAL PARSING name : String password : String homepage } entity BlogPost { poster : User body : String }
  • 9. What about incorrect and incomplete programs? entity User { name : String                                                    NORMAL PARSING password : String homepage                                                                           ERROR } entity BlogPost { Parse failure: poster : User No abstract syntax tree body : String }                                                            NEVER PARSED
  • 10. Mini-Demo Error Recovery in a data modeling language
  • 11. Parsing with SDF and SGLR • Language composition without shift/reduce conflicts • Ambiguities can be inspected • Declarative disambiguation
  • 12. Normal LR Parser token token token token token x Recovery: Backtracking, skip/insert tokens, etc. (S)GLR Parser token x token token token token token x token x Recovery: ?
  • 13. Do we really need to dive into this intimidating algorithm?
  • 14. Island Grammars  [Van Deursen & Kuipers, 1999] • Parse only interesting bits (Islands) • Skip the remaining characters (Water) IDENTIFICATION DIVISION. PROGRAM-ID. EXAMPLE.                                                                                          WATER PROCEDURE DIVISION. CALL X. YADA.                                                                                          WATER YADA YADA. CALL Y. Grammar-based “error recovery”!
  • 15. Island Grammars  [Van Deursen & Kuipers, 1999] ~[ tn]+ → WATER {avoid}
  • 17. Error Recovery Recipe 1. Take the entire Java grammar 2. Add water 3. Mix it together
  • 18. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                   ERROR } return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 19. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge;                                                                         NORMAL PARSING public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                   ERROR } return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 20. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                   ERROR                                                                          NORMAL PARSING } } return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 21. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                   ERROR                                                                          NORMAL PARSING } } return;                                                             UNEXPECTED KEYWORD } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 22. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling(); } return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } } New production: WATER → MethodDec {cons(“WATER”)} {cons(“WATER”),recover}
  • 23. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling(); } return;                                                                                          WATER } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } } New production: WATER → MethodDec {cons(“WATER”),recover} Stm {cons(“WATER”),recover}
  • 24. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling(); }                                                                                     WATER return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } } New production: WATER → Stm {cons(“WATER”),recover}
  • 25. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                  LAYOUT }                                                                                     WATER     PROBLEMATIC TOKEN return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 26. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                  LAYOUT }                                                                                     WATER     PROBLEMATIC TOKEN return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } } New production: WATER → LAYOUT {cons(“WATER”),recover}
  • 27. Mixing Java with Water public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                  LAYOUT }      WATER return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } } New production: WATER → LAYOUT {cons(“WATER”),recover}
  • 28. Reflection: Water-based Recovery Rules • • Works with any existing grammar • Can only remove fragments
  • 29. Danger of Floods public class Fridge { public void startCooling() { cooling.commence(); // missing } public void onResetButtonPress() { log.message(“Reset button pressed”); power.reboot(); } }
  • 30. Danger of Floods public class Fridge { public void startCooling() { cooling.commence(); // missing } public void onResetButtonPress() {                                                                                             WATER log.message(“Reset button pressed”); power.reboot(); } } So why not parse methods with missing closing brackets?
  • 31. Productions for Missing Literals why not add rules like this: “if” “(” Expr Stm → Stm {cons(“If”), recover} and this, and this, and this: “if” Expr “)” Stm → Stm {cons(“If”), recover} “if” Expr Stm → Stm {cons(“If”), recover} “while” “(“ Expr Stm → Stm {cons(“While”), ...} ... not going to scale.
  • 32. Productions for Missing Literals “if” “(” Expr “)” Stm → Stm {cons(“If”)} what it means internally: IF BOPEN … BCLOSE … → … [i][f] → IF [(] → BOPEN [)] → BCLOSE so, we can write (using the literal instead of BCLOSE): → BCLOSE {recover} “)” → “}” {recover}
  • 33. Applying Insertion Rules public class Fridge { public void startCooling() { cooling.commence(); // missing } public void onResetButtonPress() { log.message(“Reset button pressed”); power.reboot(); } } New production: → “}” {recover}
  • 34. Applying Insertion Rules public class Fridge { public void startCooling() { cooling.commence(); // missing }                                                                    INSERT } public void onResetButtonPress() { log.message(“Reset button pressed”); power.reboot(); } } New production: → “}” {recover}
  • 35. Recovery Rules • • Water • So who's gonna • Closing brackets (“}”) write all those recovery rules? • • Opening brackets (“{”) • • Separators (“,”) • We derive them from the • Comments grammar! • • String literals
  • 36. Customization of Recovery Rules → “class” {reject} “[|” → “|[“ {recover} “|]” → “]|” {recover}
  • 37. Putting Things Together • Water y = f ( x   + 1   ; • Insertion: “)” y = f ( x   + 1 ) ; y =     x         ; y = f ( x ) + 1   ;     f ( x   + 1 ) ; y = f       + 1   ;     f (       1 ) ; y = f (       1 ) ; y     ( x   + 1 ) ; y =   ( x ) + 1   ; y     ( x )       ; y =   ( x   + 1 ) ; y     ()          ; y =     x   + 1   ; y     (       1 ) ; y = f             ; y =           1   ; y =   ( x )       ;                   ; y = f ( )         ;
  • 38. Putting Things Together For recovery, parallel parsing does not scale...
  • 39. Putting Things Together Why not do backtracking for recovery?
  • 40. Recovery Using Backtracking public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                   ERROR } return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 41. Recovery Using Backtracking public class TemperatureMonitor { private Fridge fridge;                                                                    1. NORMAL PARSING public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                   ERROR } return; } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 42. Recovery Using Backtracking public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                   ERROR                                                                     1. NORMAL PARSING } return;                                                                   POINT OF DETECTION } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 43. Recovery Using Backtracking public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) // missing { fridge.startCooling();                                                                     1. NORMAL PARSING } return;                                                                        2. BACKTRACKING } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 44. Recovery Using Backtracking public class TemperatureMonitor { private Fridge fridge; public void trigger(Temperature temp) { if (temp.greaterThan(MAX)) { missing {                                                                   // 1 RULE fridge.startCooling(); 2 RULES 1 RULE                                                                  } 3 RULES 2 RULES 1 RULE                                                                   return;                                                                   4 RULES 3 RULES 2 RULES 1 RULE } public TemperatureMonitor(Fridge fridge) { this.fridge = fridge; } }
  • 45. Evaluation Implementation: • JSGLR • Spoofax/IMP (WebDSL, Stratego, PIL, ...) Test grammars: • Java • Java-SQL • Stratego • Stratego-Java
  • 46. Evaluation Measurements: • qualitative [Penello & DeRemer '78]: excellent / good / poor • tree alignment distance [Jian et al '94] • textual 'diffs'
  • 48. Continued Work “Natural and Flexible Error Recovery for Generated Parsers” [SLE 2009] • indentation-based region selection • fall-back mechanism • bridge parsing [Nilsson-Nyman et al, 2008] (www.strategoxt.org/Stratego/PermissiveGrammars)
  • 49. Continued Work “Natural and Flexible Error Recovery for Generated Parsers” [SLE 2009] • comparison with JDT • performance, quality • synergy between recovery techniques (www.strategoxt.org/Stratego/PermissiveGrammars)
  • 50. Conclusion SGLR/SDF • modular specifications • composable languages Recovery production rules • transparent • flexible • language-independent www.strategoxt.org/Stratego/PermissiveGrammars www.strategoxt.org/Stratego/Spoofax­IMP www.lennartkats.net Software Engineering Research Group