SlideShare una empresa de Scribd logo
1 de 50
Descargar para leer sin conexión
Parser Combinators
                              Writing external DSLs




Wednesday, November 9, 2011
DSLs

                   • DSL is an ultimate abstraction
                   • You create a language that precisely
                          describes the problem you are trying to
                          solve.




Wednesday, November 9, 2011
Internal & External

                   • DSL can be internal - made using the host
                          programming language.
                   • Or external - you invent a little language
                          for solving your problem.




Wednesday, November 9, 2011
Internal DSL: Good
                   • No external tool dependencies
                   • Nice IDE support
                   • Type checking for free
                   • Easy to implement
                   • Gives full power of your language
                   • Parsing is free
Wednesday, November 9, 2011
Internal DSL: Bad

                   • It requires expressive language
                   • If the language is not expressive enough
                          DSL will be verbose and not pleasant to
                          use
                   • It can produce obscure error messages

Wednesday, November 9, 2011
External DSL: Good

                   • Platform independent
                   • Nicer syntax
                   • External tool can perform static analysis
                   • Good error messages

Wednesday, November 9, 2011
External DSLs: Bad


                   • No IDE support
                   • Hard to implement


Wednesday, November 9, 2011
External DSLs

                   • External DSLs can be implemented using
                          interpretation or code generation.
                   • Parse
                   • Analyze
                   • Interpret | Generate Code

Wednesday, November 9, 2011
parseJSON :: String -> Either Error JSONObject




Wednesday, November 9, 2011
JSON Grammar-like stuff
               object := '{' fields? '}'
               fields := field (',' field)*
               field := id ':' value
               value := literal | object | array




Wednesday, November 9, 2011
Bison (C)
                               ANTLR (Java and many others)
                              You can encode grammar by hand




Wednesday, November 9, 2011
function parseObject() {
       match('{')
       if (lookahead(ID))
         parseFields()
       match('}')
     }




Wednesday, November 9, 2011
function parseFields() {
       parseField()
       while (lookahead(',')) {
         consume()
         parseField()
       }
     }




Wednesday, November 9, 2011
• Parser can either consume some input or
                          not.

                   • Parser can fail or succeed.
                   • Parser can return some value.


Wednesday, November 9, 2011
• Usually sequences are just sequential calls.
                   • Optional parts of grammar are just IFs
                   • Zero or more elements is WHILE
                   • Grammar rule is a function


Wednesday, November 9, 2011
function parseFields() {
       separatedBy(',', parseField)
     }

     function separatedBy(ch, f) {
       f()
       while (lookahead(ch)) {
         consume()
         f()
       }
     }



Wednesday, November 9, 2011
function sepBy(ch, p) {
       return
         seq(p, many(seq(ch, p)))
     }




Wednesday, November 9, 2011
Combinator pattern




Wednesday, November 9, 2011
Haskell in 60 seconds



Wednesday, November 9, 2011
main = putStrLn "Hello World!"

     times x n = x * n
     times = x n -> x * n
     times = x -> n -> x * n
     times = (*)
     times 2 3
     2 `times` 3
     data Point = Point Int Int
     data Either a b = Left a | Right b
     Point 10 20
     Left “Hello”


Wednesday, November 9, 2011
import Text.Parsec

     parse ::
         Parser
      -> SourceName
      -> String
      -> Either ParseError a




Wednesday, November 9, 2011
p = satisfy (x -> x == 'a')
     main = print (parse p "<test>" "abc")

     > Right 'a'

     p = satisfy (x -> x == 'a')
     main = print (parse p "<test>" "bcd")

     > Left "<test>" (line 1, column 1):
     > unexpected "b"



Wednesday, November 9, 2011
-- There is something like this in Parsec
     char c = satisfy (x -> x == c)

     -- Example
     p = char 'a'
     main = print (parse p "<test>" "bcd")

     > Left "<test>" (line 1, column 1):
     > unexpected "b"
     > expecting "a"



Wednesday, November 9, 2011
char c = satisfy (==c)   <?> show [c]




Wednesday, November 9, 2011
p = char 'a' >>= x ->
         char 'b' >>= y ->
         return [x, y]
     main = print (parse p "<test>" "abc")

     > Right "ab"




Wednesday, November 9, 2011
p = do char 'a'
            char 'b'
            return "ab"
     main = print (parse p "<test>" "abc")

     > Right "ab"




Wednesday, November 9, 2011
p = do char 'a'
            char 'b' <|> char 'q'
            char 'c' <|> char 'd'

     main = print (parse p "<test>" "abc")




Wednesday, November 9, 2011
letter = satisfy isAlpha <?> "letter"
     digit = satisfy isDigit <?> "digit"
     spaces = skipMany space <?> "white space"

     many p = ... censored ...




Wednesday, November 9, 2011
p = do letter
            many (letter <|> digit)
     main = print (parse p "<test>" "hello123")

     > Right "ello123"




Wednesday, November 9, 2011
p = do x <- letter
            xs <- many (letter <|> digit)
            return (x:xs)
     main = print (parse p "<test>" "hello123")

     > Right "hello123"




Wednesday, November 9, 2011
ident = do x <- letter
                xs <- many (letter <|> digit)
                return (x:xs)
     p = ident
     main = print (parse p "<test>" "123hello")

     > Left "<test>" (line 1, column 1):
     > unexpected "1"
     > expecting letter




Wednesday, November 9, 2011
ident = do x <- letter
                xs <- many (letter <|> digit)
                return (x:xs)
     p = ident <?> "variable name"
     main = print (parse p "<test>" "123hello")

     > Left "<test>" (line 1, column 1):
     > unexpected "1"
     > expecting variable name




Wednesday, November 9, 2011
ident = do x <- letter
                xs <- many (letter <|> digit)
                return (x:xs)
             <?> "variable name"
     p = ident
     main = print (parse p "<test>" "123hello")




Wednesday, November 9, 2011
ident = do x <- letter
                xs <- many (letter <|> digit)
                return (x:xs)
             <?> "variable name"
     letKeyword = string "let"
     p = ident <|> letKeyword
     main = print (parse p "<test>" "letter")

     > Right "letter"




Wednesday, November 9, 2011
ident = do x <- letter
                xs <- many (letter <|> digit)
                return (x:xs)
             <?> "variable name"
     letKeyword = do s <- string "let"
                     notFollowedBy (letter <|> digit)
                     spaces
                     return s
     p = try(letKeyword) <|> ident
     main = print (parse p "<test>" "letter")
     -----
     Right "letter"




Wednesday, November 9, 2011
Lexer-like example



Wednesday, November 9, 2011
type Name = String
     data Expr = Number Integer
               | Var Name
               | Let Name Expr
               | Seq [Expr]
               deriving Show




Wednesday, November 9, 2011
myDef = emptyDef {
         identStart = letter <|> char '_',
         identLetter = alphaNum <|> char '_',
         opStart = opLetter myDef,
         opLetter = oneOf "=,;",
         reservedOpNames = [
            ",", ";", "="
         ],
         reservedNames = ["let"],
         caseSensitive = True
       }




Wednesday, November 9, 2011
tokenParser = PT.makeTokenParser myDef

     parens = PT.parens tokenParser
     naturalNumber = PT.natural tokenParser
     keyword = PT.reserved tokenParser
     identifier = PT.identifier tokenParser
     op = PT.reservedOp tokenParser
     commaSep = PT.commaSep tokenParser
     commaSep1 = PT.commaSep1 tokenParser




Wednesday, November 9, 2011
simple = numberLiteral <|> var

     numberLiteral = do n <- naturalNumber
                        return $ Number n

     var = do s <- identifier
              return $ Var s




Wednesday, November 9, 2011
letStmt = do keyword "let"
                  defs <- commaSep1 def
                  op ";"
                  return $ Seq defs

     def = do name <- identifier
              op "="
              value <- simple
              return $ Let name value




Wednesday, November 9, 2011
main = print (
         parse letStmt "<test>" "let one = 1, two = 2;"
       )

     ----

     Right (
       Seq [
         Let "one" (Number 1),
         Let "two" (Number 2)
       ]
     )



Wednesday, November 9, 2011
CSV Parser Example



Wednesday, November 9, 2011
import Text.Parsec

     csvFile                  = line `endBy1` eol
     line                     = cell `sepBy` (char ',')
     cell                     = wsopt >> many (noneOf ",n")
     wsopt                    = many (oneOf " t")
     eol                      = char 'n'
     main                     = print (parse csvFile "<test>" input)
       where                  input = "aa, b,cnd,e,fn"




     > Right [["aa","b","c"],["d","e","f"]]


Wednesday, November 9, 2011
import scala.util.parsing.combinator._

     object CSVParser extends RegexParsers {
       override def skipWhitespace = false
       def whitespace = """[ t]*"""r
       def csv = rep1sep(row, "n") <~ "n"
       def row = rep1sep(field, ",")
       def field = opt(whitespace) ~> """[^n,]""".r
       def parse(s: String) = parseAll(csv, s)
     }
     println(CSVParser.parse("a,b,cnd,e, fn"))



     > [3.1] parsed: List(List(a, b, c), List(d, e, f))


Wednesday, November 9, 2011
Pysec for Python
     Spirit for C++
     In standard library of Scala
     A lot of others...




Wednesday, November 9, 2011
Stuff to read

                   • Language Implementation Patterns:
                          Create Your Own Domain-Specific and
                          General Programming Languages
                          by Terence Parr




Wednesday, November 9, 2011
Stuff to read


                   • Domain Specific Languages
                          by Martin Fowler




Wednesday, November 9, 2011
Stuff to read


                   • http://learnyouahaskell.com/
                          Learn You a Haskell for a Great Good




Wednesday, November 9, 2011
The End



Wednesday, November 9, 2011

Más contenido relacionado

Similar a Parser combinators

Text Manipulation with/without Parsec
Text Manipulation with/without ParsecText Manipulation with/without Parsec
Text Manipulation with/without Parsecujihisa
 
Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)
Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)
Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)OpenBlend society
 
Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)benwaine
 
Javascript the Language of the Web
Javascript the Language of the WebJavascript the Language of the Web
Javascript the Language of the Webandersjanmyr
 
De vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored proceduresDe vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored proceduresNorman Clarke
 
Lecture 22
Lecture 22Lecture 22
Lecture 22rhshriva
 
A Tour Through the Groovy Ecosystem
A Tour Through the Groovy EcosystemA Tour Through the Groovy Ecosystem
A Tour Through the Groovy EcosystemLeonard Axelsson
 
Web Scraping using Diazo!
Web Scraping using Diazo!Web Scraping using Diazo!
Web Scraping using Diazo!pythonchile
 
Open course(programming languages) 20150225
Open course(programming languages) 20150225Open course(programming languages) 20150225
Open course(programming languages) 20150225JangChulho
 
codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)
codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)
codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)codin9cafe
 
Perl 5.10
Perl 5.10Perl 5.10
Perl 5.10acme
 
Dynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship groupDynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship groupReuven Lerner
 
D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4Jan Berdajs
 
Localizing iOS Apps
Localizing iOS AppsLocalizing iOS Apps
Localizing iOS Appsweissazool
 
international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPsmueller_sandsmedia
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not ScalaJustin Lee
 

Similar a Parser combinators (20)

Text Manipulation with/without Parsec
Text Manipulation with/without ParsecText Manipulation with/without Parsec
Text Manipulation with/without Parsec
 
Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)
Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)
Java SE 7 - The Platform Evolves, Dalibor Topić (Oracle)
 
Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)
 
Javascript the Language of the Web
Javascript the Language of the WebJavascript the Language of the Web
Javascript the Language of the Web
 
Ruby struct
Ruby structRuby struct
Ruby struct
 
De vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored proceduresDe vuelta al pasado con SQL y stored procedures
De vuelta al pasado con SQL y stored procedures
 
Lecture 22
Lecture 22Lecture 22
Lecture 22
 
A Tour Through the Groovy Ecosystem
A Tour Through the Groovy EcosystemA Tour Through the Groovy Ecosystem
A Tour Through the Groovy Ecosystem
 
Web Scraping using Diazo!
Web Scraping using Diazo!Web Scraping using Diazo!
Web Scraping using Diazo!
 
22 spam
22 spam22 spam
22 spam
 
Open course(programming languages) 20150225
Open course(programming languages) 20150225Open course(programming languages) 20150225
Open course(programming languages) 20150225
 
codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)
codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)
codin9cafe[2015.02.25]Open course(programming languages) - 장철호(Ch Jang)
 
Perl 5.10
Perl 5.10Perl 5.10
Perl 5.10
 
Dynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship groupDynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship group
 
D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4
 
Localizing iOS Apps
Localizing iOS AppsLocalizing iOS Apps
Localizing iOS Apps
 
P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
 
Ruby
RubyRuby
Ruby
 
international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHP
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not Scala
 

Último

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...apidays
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
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.pdfsudhanshuwaghmare1
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
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 DevelopmentsTrustArc
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
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...DianaGray10
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
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...Drew Madelung
 

Último (20)

+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 - 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...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
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
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
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 New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
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...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
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...
 

Parser combinators

  • 1. Parser Combinators Writing external DSLs Wednesday, November 9, 2011
  • 2. DSLs • DSL is an ultimate abstraction • You create a language that precisely describes the problem you are trying to solve. Wednesday, November 9, 2011
  • 3. Internal & External • DSL can be internal - made using the host programming language. • Or external - you invent a little language for solving your problem. Wednesday, November 9, 2011
  • 4. Internal DSL: Good • No external tool dependencies • Nice IDE support • Type checking for free • Easy to implement • Gives full power of your language • Parsing is free Wednesday, November 9, 2011
  • 5. Internal DSL: Bad • It requires expressive language • If the language is not expressive enough DSL will be verbose and not pleasant to use • It can produce obscure error messages Wednesday, November 9, 2011
  • 6. External DSL: Good • Platform independent • Nicer syntax • External tool can perform static analysis • Good error messages Wednesday, November 9, 2011
  • 7. External DSLs: Bad • No IDE support • Hard to implement Wednesday, November 9, 2011
  • 8. External DSLs • External DSLs can be implemented using interpretation or code generation. • Parse • Analyze • Interpret | Generate Code Wednesday, November 9, 2011
  • 9. parseJSON :: String -> Either Error JSONObject Wednesday, November 9, 2011
  • 10. JSON Grammar-like stuff object := '{' fields? '}' fields := field (',' field)* field := id ':' value value := literal | object | array Wednesday, November 9, 2011
  • 11. Bison (C) ANTLR (Java and many others) You can encode grammar by hand Wednesday, November 9, 2011
  • 12. function parseObject() { match('{') if (lookahead(ID)) parseFields() match('}') } Wednesday, November 9, 2011
  • 13. function parseFields() { parseField() while (lookahead(',')) { consume() parseField() } } Wednesday, November 9, 2011
  • 14. • Parser can either consume some input or not. • Parser can fail or succeed. • Parser can return some value. Wednesday, November 9, 2011
  • 15. • Usually sequences are just sequential calls. • Optional parts of grammar are just IFs • Zero or more elements is WHILE • Grammar rule is a function Wednesday, November 9, 2011
  • 16. function parseFields() { separatedBy(',', parseField) } function separatedBy(ch, f) { f() while (lookahead(ch)) { consume() f() } } Wednesday, November 9, 2011
  • 17. function sepBy(ch, p) { return seq(p, many(seq(ch, p))) } Wednesday, November 9, 2011
  • 19. Haskell in 60 seconds Wednesday, November 9, 2011
  • 20. main = putStrLn "Hello World!" times x n = x * n times = x n -> x * n times = x -> n -> x * n times = (*) times 2 3 2 `times` 3 data Point = Point Int Int data Either a b = Left a | Right b Point 10 20 Left “Hello” Wednesday, November 9, 2011
  • 21. import Text.Parsec parse :: Parser -> SourceName -> String -> Either ParseError a Wednesday, November 9, 2011
  • 22. p = satisfy (x -> x == 'a') main = print (parse p "<test>" "abc") > Right 'a' p = satisfy (x -> x == 'a') main = print (parse p "<test>" "bcd") > Left "<test>" (line 1, column 1): > unexpected "b" Wednesday, November 9, 2011
  • 23. -- There is something like this in Parsec char c = satisfy (x -> x == c) -- Example p = char 'a' main = print (parse p "<test>" "bcd") > Left "<test>" (line 1, column 1): > unexpected "b" > expecting "a" Wednesday, November 9, 2011
  • 24. char c = satisfy (==c) <?> show [c] Wednesday, November 9, 2011
  • 25. p = char 'a' >>= x -> char 'b' >>= y -> return [x, y] main = print (parse p "<test>" "abc") > Right "ab" Wednesday, November 9, 2011
  • 26. p = do char 'a' char 'b' return "ab" main = print (parse p "<test>" "abc") > Right "ab" Wednesday, November 9, 2011
  • 27. p = do char 'a' char 'b' <|> char 'q' char 'c' <|> char 'd' main = print (parse p "<test>" "abc") Wednesday, November 9, 2011
  • 28. letter = satisfy isAlpha <?> "letter" digit = satisfy isDigit <?> "digit" spaces = skipMany space <?> "white space" many p = ... censored ... Wednesday, November 9, 2011
  • 29. p = do letter many (letter <|> digit) main = print (parse p "<test>" "hello123") > Right "ello123" Wednesday, November 9, 2011
  • 30. p = do x <- letter xs <- many (letter <|> digit) return (x:xs) main = print (parse p "<test>" "hello123") > Right "hello123" Wednesday, November 9, 2011
  • 31. ident = do x <- letter xs <- many (letter <|> digit) return (x:xs) p = ident main = print (parse p "<test>" "123hello") > Left "<test>" (line 1, column 1): > unexpected "1" > expecting letter Wednesday, November 9, 2011
  • 32. ident = do x <- letter xs <- many (letter <|> digit) return (x:xs) p = ident <?> "variable name" main = print (parse p "<test>" "123hello") > Left "<test>" (line 1, column 1): > unexpected "1" > expecting variable name Wednesday, November 9, 2011
  • 33. ident = do x <- letter xs <- many (letter <|> digit) return (x:xs) <?> "variable name" p = ident main = print (parse p "<test>" "123hello") Wednesday, November 9, 2011
  • 34. ident = do x <- letter xs <- many (letter <|> digit) return (x:xs) <?> "variable name" letKeyword = string "let" p = ident <|> letKeyword main = print (parse p "<test>" "letter") > Right "letter" Wednesday, November 9, 2011
  • 35. ident = do x <- letter xs <- many (letter <|> digit) return (x:xs) <?> "variable name" letKeyword = do s <- string "let" notFollowedBy (letter <|> digit) spaces return s p = try(letKeyword) <|> ident main = print (parse p "<test>" "letter") ----- Right "letter" Wednesday, November 9, 2011
  • 37. type Name = String data Expr = Number Integer | Var Name | Let Name Expr | Seq [Expr] deriving Show Wednesday, November 9, 2011
  • 38. myDef = emptyDef { identStart = letter <|> char '_', identLetter = alphaNum <|> char '_', opStart = opLetter myDef, opLetter = oneOf "=,;", reservedOpNames = [ ",", ";", "=" ], reservedNames = ["let"], caseSensitive = True } Wednesday, November 9, 2011
  • 39. tokenParser = PT.makeTokenParser myDef parens = PT.parens tokenParser naturalNumber = PT.natural tokenParser keyword = PT.reserved tokenParser identifier = PT.identifier tokenParser op = PT.reservedOp tokenParser commaSep = PT.commaSep tokenParser commaSep1 = PT.commaSep1 tokenParser Wednesday, November 9, 2011
  • 40. simple = numberLiteral <|> var numberLiteral = do n <- naturalNumber return $ Number n var = do s <- identifier return $ Var s Wednesday, November 9, 2011
  • 41. letStmt = do keyword "let" defs <- commaSep1 def op ";" return $ Seq defs def = do name <- identifier op "=" value <- simple return $ Let name value Wednesday, November 9, 2011
  • 42. main = print ( parse letStmt "<test>" "let one = 1, two = 2;" ) ---- Right ( Seq [ Let "one" (Number 1), Let "two" (Number 2) ] ) Wednesday, November 9, 2011
  • 43. CSV Parser Example Wednesday, November 9, 2011
  • 44. import Text.Parsec csvFile = line `endBy1` eol line = cell `sepBy` (char ',') cell = wsopt >> many (noneOf ",n") wsopt = many (oneOf " t") eol = char 'n' main = print (parse csvFile "<test>" input) where input = "aa, b,cnd,e,fn" > Right [["aa","b","c"],["d","e","f"]] Wednesday, November 9, 2011
  • 45. import scala.util.parsing.combinator._ object CSVParser extends RegexParsers { override def skipWhitespace = false def whitespace = """[ t]*"""r def csv = rep1sep(row, "n") <~ "n" def row = rep1sep(field, ",") def field = opt(whitespace) ~> """[^n,]""".r def parse(s: String) = parseAll(csv, s) } println(CSVParser.parse("a,b,cnd,e, fn")) > [3.1] parsed: List(List(a, b, c), List(d, e, f)) Wednesday, November 9, 2011
  • 46. Pysec for Python Spirit for C++ In standard library of Scala A lot of others... Wednesday, November 9, 2011
  • 47. Stuff to read • Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages by Terence Parr Wednesday, November 9, 2011
  • 48. Stuff to read • Domain Specific Languages by Martin Fowler Wednesday, November 9, 2011
  • 49. Stuff to read • http://learnyouahaskell.com/ Learn You a Haskell for a Great Good Wednesday, November 9, 2011