SlideShare a Scribd company logo
Monadic parsers
Alexander Granin
graninas@gmail.com
C++ Russia 2019, Moscow
1
С++ Siberia 2019, Keynote
The Present and the Future of Functional Programming in C++
С++ Russia 2018
Functional Approach to Software Transactional Memory in C++
С++ Russia 2016
Functional “Life”: Parallel Cellular Automata and Comonads in C++
С++ Siberia 2015
Functional Microscope: Lenses in C++
С++ User Group 2014
Functional and Declarative Design in C++
3
struct Presentation
{
Introduction
Parsing and Backus-Naur form
boost::spirit (qi)
cpp_parsec_free
Monadic parsers
State & context-sensitive grammars
Conclusion
};
4
age
integer
first name
string
last name
string
salary
float
employee {35, “Jane”, “Street”, 54321}
struct Employee
{
int age;
string firstName;
string lastName;
double salary;
};
Parsing
5
employee ::=
"employee" spaces
"{" spaces
age "," spaces
firstName "," spaces
lastName "," spaces
salary spaces
"}"
Backus-Naur Form
quotedString ::= '"' string '"'
age ::= integer
firstName ::= quotedString
lastName ::= quotedString
salary ::= double
6
boost::spirit (Qi)
7
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %= lit("employee") >> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_ >> '}';
}
8
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %= lit("employee") >> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_ >> '}';
}
qi::rule<Iterator, string(), ascii::space_type> quoted_string;
qi::rule<Iterator, employee(), ascii::space_type> start;
9
template <typename Iterator>
struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>{
employee_parser() : employee_parser::base_type(start) {
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %= lit("employee") >> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_ >> '}';
}
qi::rule<Iterator, string(), ascii::space_type> quoted_string;
qi::rule<Iterator, employee(), ascii::space_type> start;
};
10
template <typename Iterator>
struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>{
employee_parser() : employee_parser::base_type(start) {
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %= lit("employee") >> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_ >> '}';
}
qi::rule<Iterator, string(), ascii::space_type> quoted_string;
qi::rule<Iterator, employee(), ascii::space_type> start;
};
11
12
cpp_parsec_free
13
ParserT<Employee> employee =
app<Employee, int, string, string, double>(
mkEmployee,
prefix >> intP,
comma >> quotedString,
comma >> quotedString,
comma >> (doubleP << postfix));
14
ParserT<Employee> employee =
app<Employee, int, string, string, double>(
mkEmployee,
prefix >> intP,
comma >> quotedString,
comma >> quotedString,
comma >> (doubleP << postfix));
auto prefix = lit("employee") >> between(spaces, symbol('{'));
auto postfix = between(spaces, symbol('}'));
auto comma = symbol(',') >> spaces;
auto mkEmployee =
[](int a, const string& sn, const string& fn, double s) {
return Employee {a, sn, fn, s};
};
15
auto s = "employee {35, “Jane”, “Street”, 54321}";
ParserResult<Employee> result = parse(employee, s);
16
auto s = "employee {35, “Jane”, “Street”, 54321}";
ParserResult<Employee> result = parse(employee, s);
if (isLeft(result)) {
std::cout << "Parse error: " << getError(result).message;
}
else {
Employee employee = getParsed(result);
}
17
Parser combinators
18
ParserT<int> intP; // integer number
ParserT<double> doubleP; // double precision float
ParserT<Char> digit; // 0..9
ParserT<Char> lower; // a..z
ParserT<Char> upper; // A..Z
ParserT<Char> letter; // a..z A..Z
ParserT<Char> alphaNum; // 0..9 a..z A..Z
ParserT<Char> symbol(Char ch); // symbol
ParserT<string> lit(const string&); // string
Basic parsers
19
template <typename A, typename B>
ParserT<A> fst(const ParserT<A>& p1, const ParserT<B>& p2);
template <typename A, typename B>
ParserT<B> snd(const ParserT<A>& p1, const ParserT<B>& p2);
Parser combinators
20
template <typename A, typename B>
ParserT<A> fst(const ParserT<A>& p1, const ParserT<B>& p2);
template <typename A, typename B>
ParserT<B> snd(const ParserT<A>& p1, const ParserT<B>& p2);
// fst
template <typename A, typename B>
ParserT<A> operator<< (const ParserT<A>& l, const ParserT<B>& r);
// snd
template <typename A, typename B>
ParserT<B> operator>> (const ParserT<A>& l, const ParserT<B>& r);
Parser combinators
21
ParserT<string> helloWorld =
snd(lit("Hello"), snd(symbol(' '), lit("world")));
ParserT<string> helloWorld =
lit("Hello") >> symbol(' ') >> lit("world");
Parsing “Hello world”
22
template <typename A>
ParserT<Many<A>> many(const ParserT<A>& p); // 0 or many
template <typename A>
ParserT<Many<A>> many1(const ParserT<A>& p); // 1 or many
template <typename A, typename B>
ParserT<B> between(const ParserT<A>& bracketP, // between
const ParserT<B>& p);
More combinators
23
template <typename A>
ParserT<A> alt(const ParserT<A>& l, const ParserT<A>& r);
template <typename A>
ParserT<A> operator| (const ParserT<A>& l, const ParserT<A>& r);
Alternative
24
template <typename A>
ParserT<A> alt(const ParserT<A>& l, const ParserT<A>& r);
template <typename A>
ParserT<A> operator| (const ParserT<A>& l, const ParserT<A>& r);
ParserT<string> boolean = alt(lit("true"), lit("false"));
ParserT<string> currency = lit("EUR") | lit("USD") | lit("GBP");
Alternative
25
Monadic parsers
26
Functor
fmap :: (A -> B) -> ParserT<A> -> ParserT<B>
Applicative
app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C>
Monad
bind :: ParserT<A> -> (A -> ParserT<B>)
27
fmap :: (A -> B) -> ParserT<A> -> ParserT<B>
template <typename A, typename B>
ParserT<B> fmap(const function<B(A)>& f, const ParserT<A>& p);
Functor
28
fmap :: (A -> B) -> ParserT<A> -> ParserT<B>
template <typename A, typename B>
ParserT<B> fmap(const function<B(A)>& f, const ParserT<A>& p);
ParserT<string> strBoolean = lit("true") | lit("false");
Functor
29
fmap :: (A -> B) -> ParserT<A> -> ParserT<B>
template <typename A, typename B>
ParserT<B> fmap(const function<B(A)>& f, const ParserT<A>& p);
ParserT<string> strBoolean = lit("true") | lit("false");
ParserT<bool> boolean = fmap<string, bool>(f, strBoolean);
function<bool(string)> f = [](const string& s) {
return s == "true";
};
Functor
30
Functor
fmap :: (A -> B) -> ParserT<A> -> ParserT<B>
Applicative
app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C>
Monad
bind :: ParserT<A> -> (A -> ParserT<B>)
31
app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C>
template <typename A, typename B, typename C>
ParserT<C> app(const function<C(A, B)>& f,
const ParserT<A>& a, const ParserT<B>& b);
Applicative
32
app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C>
template <typename A, typename B, typename C>
ParserT<C> app(const function<C(A, B)>& f,
const ParserT<A>& a, const ParserT<B>& b);
ParserT<string> helloUsername = app<string, string>(
mkHello,
letters,
spaces >> letters);
string mkHello = [](const string& firstName, const string& secondName) {
return string("Hello, ") + firstName + " " + secondName + "!"; };
Applicative
33
ParserT<Value> value = app(mkValue, intP | doubleP);
Applicative is combinable
34
ParserT<Value> value = app(mkValue, intP | doubleP);
ParserT<BinOp> binOp = app(mkBinOp,
symbol('+') | symbol('-') | symbol('*') | symbol('/'));
Applicative is combinable
35
ParserT<Value> value = app(mkValue, intP | doubleP);
ParserT<BinOp> binOp = app(mkBinOp,
symbol('+') | symbol('-') | symbol('*') | symbol('/'));
ParserT<FuncArgs> funcArgs = app(mkFuncArgs,
expr, opt(symbol(',') >> funcArgs));
Applicative is combinable
36
ParserT<Value> value = app(mkValue, intP | doubleP);
ParserT<BinOp> binOp = app(mkBinOp,
symbol('+') | symbol('-') | symbol('*') | symbol('/'));
ParserT<FuncArgs> funcArgs = app(mkFuncArgs,
expr, opt(symbol(',') >> funcArgs));
ParserT<FuncCall> funcCall = app(mkFuncCall,
identifier, between('(', ')', funcArgs));
Applicative is combinable
37
ParserT<Value> value = app(mkValue, intP | doubleP);
ParserT<BinOp> binOp = app(mkBinOp,
symbol('+') | symbol('-') | symbol('*') | symbol('/'));
ParserT<FuncArgs> funcArgs = app(mkFuncArgs,
expr, opt(symbol(',') >> funcArgs));
ParserT<FuncCall> funcCall = app(mkFuncCall,
identifier, between('(', ')', funcArgs));
ParserT<BinExpr> binExpr = app(mkBinExpr, expr, binOp, expr);
Applicative is combinable
38
ParserT<Value> value = app(mkValue, intP | doubleP);
ParserT<BinOp> binOp = app(mkBinOp,
symbol('+') | symbol('-') | symbol('*') | symbol('/'));
ParserT<FuncArgs> funcArgs = app(mkFuncArgs,
expr, opt(symbol(',') >> funcArgs));
ParserT<FuncCall> funcCall = app(mkFuncCall,
identifier, between('(', ')', funcArgs));
ParserT<BinExpr> binExpr = app(mkBinExpr, expr, binOp, expr);
ParserT<Expr> expr = app(mkExpr, binExpr | funcCall | value);
Applicative is combinable
39
Functor
fmap :: (A -> B) -> ParserT<A> -> ParserT<B>
Applicative
app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<B>
Monad
bind :: ParserT<A> -> (A -> ParserT<B>)
40
template <typename A>
ParserT<A> pure(const A& a);
template <typename A, typename B>
ParserT<B> bind(
const ParserT<A>& ma,
const function<ParserT<B>(A)>& f);
ParserT monad
41
ParserT<string> helloUsername =
bind<string, string>(letters, [=](auto firstName) {
return bind<string, string>(spaces, [=](auto) {
return bind<string, string>(letters, [=](auto lastName) {
return pure<string>(mkHello(firstName, lastName)); }); }); });
ParserT<string> helloUsername =
bind<string, string>(letters, [=](auto firstName) { return
bind<string, string>(spaces, [=](auto) { return
bind<string, string>(letters, [=](auto lastName) { return
pure<string>(mkHello(firstName, lastName)); }); }); });
Monadic binding
42
ParserT<string> helloUsername =
bind<string, string>(letters, [=](auto firstName) {
return bind<string, string>(spaces, [=](auto) {
return bind<string, string>(letters, [=](auto lastName) {
return pure<string>(mkHello(firstName, lastName)); }); }); });
ParserT<string> helloUsername =
bind<string, string>(letters, [=](auto firstName) { return
bind<string, string>(spaces, [=](auto) { return
bind<string, string>(letters, [=](auto lastName) { return
pure<string>(mkHello(firstName, lastName)); }); }); });
Monadic binding, reformatted
43
ParserT<string> helloUsername = do {
auto firstName <- letters;
auto _ <- spaces;
auto lastName <- letters;
return pure<string>(mkHello(firstName, lastName));
};
Dear Santa, I was a good boy last year. Can I have?..
44
State & context-sensitive grammars
45
age
integer
first name
string
last name
string
salary
float
employee {35, “Jane”, “Street”, 54321}
address {35, “Jane”, “Street”, 54321}
house
integer
title
string
post index
integer
type
string
46
struct Employee {
int age;
string firstName;
string lastName;
double salary;
};
47
struct Address {
int house;
string title;
string name;
int postIndex;
};
Algebraic Data Type
struct Employee {
int age;
string firstName;
string lastName;
double salary;
};
48
struct Address {
int house;
string title;
string name;
int postIndex;
};
using LogEntry = std::variant<Employee, Address>;
Algebraic Data Type
struct Employee {
int age;
string firstName;
string lastName;
double salary;
};
49
struct Address {
int house;
string title;
string name;
int postIndex;
};
using LogEntry = std::variant<Employee, Address>;
function<LogEntry(int a, const string& fn, const string& ln, double s)>
mkEmployeeEntry;
function<LogEntry(int h, const string& ttl, const string& n, int idx)>
mkAddressEntry;
Algebraic Data Type
struct Config {
string currentEntry;
};
ParserT<Config, string> logToken = lit("employee") | lit("address");
ParserT<Config, Unit> setEntry = bind<string, Unit>(
logToken,
[](const string& s) {
return putSt(Config { s });
});
Putting state
50
struct Config {
string currentEntry;
};
ParserT<Config, string> logToken = lit("employee") | lit("address");
ParserT<Config, Unit> setEntry = bind<string, Unit>(
logToken,
[](const string& s) {
return putSt(Config { s });
});
Putting state
51
ParserT<Config, LogEntry> logEntry =
bind<Config, LogEntry>(getSt, [=](Config cfg) {
if (cfg.currentEntry == "employee")
return fmap(mkEmployeeEntry, employeeParser);
return fmap(mkAddressEntry, addressParser);
});
Getting state
52
ParserT<Config, LogEntry> logEntry =
bind<Config, LogEntry>(getSt, [=](Config cfg) {
if (cfg.currentEntry == "employee")
return fmap(mkEmployeeEntry, employeeParser);
return fmap(mkAddressEntry, addressParser);
});
Getting state
53
Conclusion
54
Monadic parser combinators
● Monad: do-notation, bind, when, unless, sequence, mapM, guard
● Applicative: app, pure
● Alternative: alt, operator|
● Functor: fmap
● Time travelling: lookForward, lookBackward
● State handling: getSt, putSt
● Error handling: tryP, safeP, onFail, onSuccess, failWith
55
56
GitHub List: Functional Programming in C++
https://github.com/graninas/cpp_functional_programming��
● Books
● Articles
● Papers
● Talks
● QA
● Libraries
● Showcase projects
Thanks for watching!
Alexander Granin
graninas@gmail.com
Twitter: @graninas
C++ Russia 2019, Moscow
57
Monadic parsers in C++

More Related Content

What's hot

Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output) Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output)
Aman Deep
 
Data structures lab manual
Data structures lab manualData structures lab manual
Data structures lab manual
Syed Mustafa
 
Data Structures Practical File
Data Structures Practical File Data Structures Practical File
Data Structures Practical File
Harjinder Singh
 
54602399 c-examples-51-to-108-programe-ee01083101
54602399 c-examples-51-to-108-programe-ee0108310154602399 c-examples-51-to-108-programe-ee01083101
54602399 c-examples-51-to-108-programe-ee01083101
premrings
 
C++ Programming - 11th Study
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th Study
Chris Ohk
 
VTU Data Structures Lab Manual
VTU Data Structures Lab ManualVTU Data Structures Lab Manual
VTU Data Structures Lab Manual
Nithin Kumar,VVCE, Mysuru
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»
SpbDotNet Community
 
C++ Programming - 2nd Study
C++ Programming - 2nd StudyC++ Programming - 2nd Study
C++ Programming - 2nd Study
Chris Ohk
 
project report in C++ programming and SQL
project report in C++ programming and SQLproject report in C++ programming and SQL
project report in C++ programming and SQL
vikram mahendra
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabs
Stephane Gleizes
 
Object Oriented Programming Using C++ Practical File
Object Oriented Programming Using C++ Practical FileObject Oriented Programming Using C++ Practical File
Object Oriented Programming Using C++ Practical File
Harjinder Singh
 
Computer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commandsComputer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commands
Vishvjeet Yadav
 
C++ file
C++ fileC++ file
programming in C++ report
programming in C++ reportprogramming in C++ report
programming in C++ report
vikram mahendra
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)
Geeks Anonymes
 
C++11
C++11C++11
C++11
ppd1961
 
C++11
C++11C++11
Technical questions for interview c programming
Technical questions for interview  c programmingTechnical questions for interview  c programming
Technical questions for interview c programming
CHANDAN KUMAR
 

What's hot (20)

Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output) Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output)
 
Data structures lab manual
Data structures lab manualData structures lab manual
Data structures lab manual
 
Data Structures Practical File
Data Structures Practical File Data Structures Practical File
Data Structures Practical File
 
54602399 c-examples-51-to-108-programe-ee01083101
54602399 c-examples-51-to-108-programe-ee0108310154602399 c-examples-51-to-108-programe-ee01083101
54602399 c-examples-51-to-108-programe-ee01083101
 
C++ Programming - 11th Study
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th Study
 
VTU Data Structures Lab Manual
VTU Data Structures Lab ManualVTU Data Structures Lab Manual
VTU Data Structures Lab Manual
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»
 
C++ Programming - 2nd Study
C++ Programming - 2nd StudyC++ Programming - 2nd Study
C++ Programming - 2nd Study
 
project report in C++ programming and SQL
project report in C++ programming and SQLproject report in C++ programming and SQL
project report in C++ programming and SQL
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabs
 
Object Oriented Programming Using C++ Practical File
Object Oriented Programming Using C++ Practical FileObject Oriented Programming Using C++ Practical File
Object Oriented Programming Using C++ Practical File
 
Computer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commandsComputer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commands
 
C++ file
C++ fileC++ file
C++ file
 
C++ file
C++ fileC++ file
C++ file
 
programming in C++ report
programming in C++ reportprogramming in C++ report
programming in C++ report
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)
 
Bijender (1)
Bijender (1)Bijender (1)
Bijender (1)
 
C++11
C++11C++11
C++11
 
C++11
C++11C++11
C++11
 
Technical questions for interview c programming
Technical questions for interview  c programmingTechnical questions for interview  c programming
Technical questions for interview c programming
 

Similar to Monadic parsers in C++

Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17
LogeekNightUkraine
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Romain Francois
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf Edition
Paulo Morgado
 
Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#
Paulo Morgado
 
Unit 5 Foc
Unit 5 FocUnit 5 Foc
Unit 5 Foc
JAYA
 
C++ manual Report Full
C++ manual Report FullC++ manual Report Full
C++ manual Report Full
Thesis Scientist Private Limited
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
C++ Homework Help
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
Alexander Granin
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Romain Francois
 
Sparse Matrix and Polynomial
Sparse Matrix and PolynomialSparse Matrix and Polynomial
Sparse Matrix and Polynomial
Aroosa Rajput
 
Python Manuel-R2021.pdf
Python Manuel-R2021.pdfPython Manuel-R2021.pdf
Python Manuel-R2021.pdf
RamprakashSingaravel1
 
Analysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsAnalysis of Microsoft Code Contracts
Analysis of Microsoft Code Contracts
PVS-Studio
 
JS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless BebopJS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless Bebop
JSFestUA
 
Theory3
Theory3Theory3
C programming
C programmingC programming
C programming
Karthikeyan A K
 
Assignment c programming
Assignment c programmingAssignment c programming
Assignment c programming
Icaii Infotech
 
Debug Information And Where They Come From
Debug Information And Where They Come FromDebug Information And Where They Come From
Debug Information And Where They Come From
Min-Yih Hsu
 

Similar to Monadic parsers in C++ (20)

Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf Edition
 
Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#
 
Unit 5 Foc
Unit 5 FocUnit 5 Foc
Unit 5 Foc
 
C++ manual Report Full
C++ manual Report FullC++ manual Report Full
C++ manual Report Full
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
 
Code optimization
Code optimization Code optimization
Code optimization
 
Code optimization
Code optimization Code optimization
Code optimization
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++
 
Sparse Matrix and Polynomial
Sparse Matrix and PolynomialSparse Matrix and Polynomial
Sparse Matrix and Polynomial
 
Python Manuel-R2021.pdf
Python Manuel-R2021.pdfPython Manuel-R2021.pdf
Python Manuel-R2021.pdf
 
Analysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsAnalysis of Microsoft Code Contracts
Analysis of Microsoft Code Contracts
 
Functions
FunctionsFunctions
Functions
 
JS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless BebopJS Fest 2019. Anjana Vakil. Serverless Bebop
JS Fest 2019. Anjana Vakil. Serverless Bebop
 
Theory3
Theory3Theory3
Theory3
 
C programming
C programmingC programming
C programming
 
Assignment c programming
Assignment c programmingAssignment c programming
Assignment c programming
 
Debug Information And Where They Come From
Debug Information And Where They Come FromDebug Information And Where They Come From
Debug Information And Where They Come From
 

More from Alexander Granin

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
Alexander Granin
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monad
Alexander Granin
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
Alexander Granin
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Alexander Granin
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
Alexander Granin
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
Alexander Granin
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
Alexander Granin
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
Alexander Granin
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
Alexander Granin
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
Alexander Granin
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
Alexander Granin
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
Alexander Granin
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
Alexander Granin
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
Alexander Granin
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
Alexander Granin
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
Alexander Granin
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
Alexander Granin
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Alexander Granin
 
Идиоматичный функциональный код
Идиоматичный функциональный кодИдиоматичный функциональный код
Идиоматичный функциональный код
Alexander Granin
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
Alexander Granin
 

More from Alexander Granin (20)

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monad
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
 
Идиоматичный функциональный код
Идиоматичный функциональный кодИдиоматичный функциональный код
Идиоматичный функциональный код
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
 

Recently uploaded

openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 

Recently uploaded (20)

openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 

Monadic parsers in C++

  • 2.
  • 3. С++ Siberia 2019, Keynote The Present and the Future of Functional Programming in C++ С++ Russia 2018 Functional Approach to Software Transactional Memory in C++ С++ Russia 2016 Functional “Life”: Parallel Cellular Automata and Comonads in C++ С++ Siberia 2015 Functional Microscope: Lenses in C++ С++ User Group 2014 Functional and Declarative Design in C++ 3
  • 4. struct Presentation { Introduction Parsing and Backus-Naur form boost::spirit (qi) cpp_parsec_free Monadic parsers State & context-sensitive grammars Conclusion }; 4
  • 5. age integer first name string last name string salary float employee {35, “Jane”, “Street”, 54321} struct Employee { int age; string firstName; string lastName; double salary; }; Parsing 5
  • 6. employee ::= "employee" spaces "{" spaces age "," spaces firstName "," spaces lastName "," spaces salary spaces "}" Backus-Naur Form quotedString ::= '"' string '"' age ::= integer firstName ::= quotedString lastName ::= quotedString salary ::= double 6
  • 8. quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; start %= lit("employee") >> '{' >> int_ >> ',' >> quoted_string >> ',' >> quoted_string >> ',' >> double_ >> '}'; } 8
  • 9. quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; start %= lit("employee") >> '{' >> int_ >> ',' >> quoted_string >> ',' >> quoted_string >> ',' >> double_ >> '}'; } qi::rule<Iterator, string(), ascii::space_type> quoted_string; qi::rule<Iterator, employee(), ascii::space_type> start; 9
  • 10. template <typename Iterator> struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>{ employee_parser() : employee_parser::base_type(start) { quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; start %= lit("employee") >> '{' >> int_ >> ',' >> quoted_string >> ',' >> quoted_string >> ',' >> double_ >> '}'; } qi::rule<Iterator, string(), ascii::space_type> quoted_string; qi::rule<Iterator, employee(), ascii::space_type> start; }; 10
  • 11. template <typename Iterator> struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type>{ employee_parser() : employee_parser::base_type(start) { quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; start %= lit("employee") >> '{' >> int_ >> ',' >> quoted_string >> ',' >> quoted_string >> ',' >> double_ >> '}'; } qi::rule<Iterator, string(), ascii::space_type> quoted_string; qi::rule<Iterator, employee(), ascii::space_type> start; }; 11
  • 12. 12
  • 14. ParserT<Employee> employee = app<Employee, int, string, string, double>( mkEmployee, prefix >> intP, comma >> quotedString, comma >> quotedString, comma >> (doubleP << postfix)); 14
  • 15. ParserT<Employee> employee = app<Employee, int, string, string, double>( mkEmployee, prefix >> intP, comma >> quotedString, comma >> quotedString, comma >> (doubleP << postfix)); auto prefix = lit("employee") >> between(spaces, symbol('{')); auto postfix = between(spaces, symbol('}')); auto comma = symbol(',') >> spaces; auto mkEmployee = [](int a, const string& sn, const string& fn, double s) { return Employee {a, sn, fn, s}; }; 15
  • 16. auto s = "employee {35, “Jane”, “Street”, 54321}"; ParserResult<Employee> result = parse(employee, s); 16
  • 17. auto s = "employee {35, “Jane”, “Street”, 54321}"; ParserResult<Employee> result = parse(employee, s); if (isLeft(result)) { std::cout << "Parse error: " << getError(result).message; } else { Employee employee = getParsed(result); } 17
  • 19. ParserT<int> intP; // integer number ParserT<double> doubleP; // double precision float ParserT<Char> digit; // 0..9 ParserT<Char> lower; // a..z ParserT<Char> upper; // A..Z ParserT<Char> letter; // a..z A..Z ParserT<Char> alphaNum; // 0..9 a..z A..Z ParserT<Char> symbol(Char ch); // symbol ParserT<string> lit(const string&); // string Basic parsers 19
  • 20. template <typename A, typename B> ParserT<A> fst(const ParserT<A>& p1, const ParserT<B>& p2); template <typename A, typename B> ParserT<B> snd(const ParserT<A>& p1, const ParserT<B>& p2); Parser combinators 20
  • 21. template <typename A, typename B> ParserT<A> fst(const ParserT<A>& p1, const ParserT<B>& p2); template <typename A, typename B> ParserT<B> snd(const ParserT<A>& p1, const ParserT<B>& p2); // fst template <typename A, typename B> ParserT<A> operator<< (const ParserT<A>& l, const ParserT<B>& r); // snd template <typename A, typename B> ParserT<B> operator>> (const ParserT<A>& l, const ParserT<B>& r); Parser combinators 21
  • 22. ParserT<string> helloWorld = snd(lit("Hello"), snd(symbol(' '), lit("world"))); ParserT<string> helloWorld = lit("Hello") >> symbol(' ') >> lit("world"); Parsing “Hello world” 22
  • 23. template <typename A> ParserT<Many<A>> many(const ParserT<A>& p); // 0 or many template <typename A> ParserT<Many<A>> many1(const ParserT<A>& p); // 1 or many template <typename A, typename B> ParserT<B> between(const ParserT<A>& bracketP, // between const ParserT<B>& p); More combinators 23
  • 24. template <typename A> ParserT<A> alt(const ParserT<A>& l, const ParserT<A>& r); template <typename A> ParserT<A> operator| (const ParserT<A>& l, const ParserT<A>& r); Alternative 24
  • 25. template <typename A> ParserT<A> alt(const ParserT<A>& l, const ParserT<A>& r); template <typename A> ParserT<A> operator| (const ParserT<A>& l, const ParserT<A>& r); ParserT<string> boolean = alt(lit("true"), lit("false")); ParserT<string> currency = lit("EUR") | lit("USD") | lit("GBP"); Alternative 25
  • 27. Functor fmap :: (A -> B) -> ParserT<A> -> ParserT<B> Applicative app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C> Monad bind :: ParserT<A> -> (A -> ParserT<B>) 27
  • 28. fmap :: (A -> B) -> ParserT<A> -> ParserT<B> template <typename A, typename B> ParserT<B> fmap(const function<B(A)>& f, const ParserT<A>& p); Functor 28
  • 29. fmap :: (A -> B) -> ParserT<A> -> ParserT<B> template <typename A, typename B> ParserT<B> fmap(const function<B(A)>& f, const ParserT<A>& p); ParserT<string> strBoolean = lit("true") | lit("false"); Functor 29
  • 30. fmap :: (A -> B) -> ParserT<A> -> ParserT<B> template <typename A, typename B> ParserT<B> fmap(const function<B(A)>& f, const ParserT<A>& p); ParserT<string> strBoolean = lit("true") | lit("false"); ParserT<bool> boolean = fmap<string, bool>(f, strBoolean); function<bool(string)> f = [](const string& s) { return s == "true"; }; Functor 30
  • 31. Functor fmap :: (A -> B) -> ParserT<A> -> ParserT<B> Applicative app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C> Monad bind :: ParserT<A> -> (A -> ParserT<B>) 31
  • 32. app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C> template <typename A, typename B, typename C> ParserT<C> app(const function<C(A, B)>& f, const ParserT<A>& a, const ParserT<B>& b); Applicative 32
  • 33. app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<C> template <typename A, typename B, typename C> ParserT<C> app(const function<C(A, B)>& f, const ParserT<A>& a, const ParserT<B>& b); ParserT<string> helloUsername = app<string, string>( mkHello, letters, spaces >> letters); string mkHello = [](const string& firstName, const string& secondName) { return string("Hello, ") + firstName + " " + secondName + "!"; }; Applicative 33
  • 34. ParserT<Value> value = app(mkValue, intP | doubleP); Applicative is combinable 34
  • 35. ParserT<Value> value = app(mkValue, intP | doubleP); ParserT<BinOp> binOp = app(mkBinOp, symbol('+') | symbol('-') | symbol('*') | symbol('/')); Applicative is combinable 35
  • 36. ParserT<Value> value = app(mkValue, intP | doubleP); ParserT<BinOp> binOp = app(mkBinOp, symbol('+') | symbol('-') | symbol('*') | symbol('/')); ParserT<FuncArgs> funcArgs = app(mkFuncArgs, expr, opt(symbol(',') >> funcArgs)); Applicative is combinable 36
  • 37. ParserT<Value> value = app(mkValue, intP | doubleP); ParserT<BinOp> binOp = app(mkBinOp, symbol('+') | symbol('-') | symbol('*') | symbol('/')); ParserT<FuncArgs> funcArgs = app(mkFuncArgs, expr, opt(symbol(',') >> funcArgs)); ParserT<FuncCall> funcCall = app(mkFuncCall, identifier, between('(', ')', funcArgs)); Applicative is combinable 37
  • 38. ParserT<Value> value = app(mkValue, intP | doubleP); ParserT<BinOp> binOp = app(mkBinOp, symbol('+') | symbol('-') | symbol('*') | symbol('/')); ParserT<FuncArgs> funcArgs = app(mkFuncArgs, expr, opt(symbol(',') >> funcArgs)); ParserT<FuncCall> funcCall = app(mkFuncCall, identifier, between('(', ')', funcArgs)); ParserT<BinExpr> binExpr = app(mkBinExpr, expr, binOp, expr); Applicative is combinable 38
  • 39. ParserT<Value> value = app(mkValue, intP | doubleP); ParserT<BinOp> binOp = app(mkBinOp, symbol('+') | symbol('-') | symbol('*') | symbol('/')); ParserT<FuncArgs> funcArgs = app(mkFuncArgs, expr, opt(symbol(',') >> funcArgs)); ParserT<FuncCall> funcCall = app(mkFuncCall, identifier, between('(', ')', funcArgs)); ParserT<BinExpr> binExpr = app(mkBinExpr, expr, binOp, expr); ParserT<Expr> expr = app(mkExpr, binExpr | funcCall | value); Applicative is combinable 39
  • 40. Functor fmap :: (A -> B) -> ParserT<A> -> ParserT<B> Applicative app :: (A -> B -> C) -> ParserT<A> -> ParserT<B> -> ParserT<B> Monad bind :: ParserT<A> -> (A -> ParserT<B>) 40
  • 41. template <typename A> ParserT<A> pure(const A& a); template <typename A, typename B> ParserT<B> bind( const ParserT<A>& ma, const function<ParserT<B>(A)>& f); ParserT monad 41
  • 42. ParserT<string> helloUsername = bind<string, string>(letters, [=](auto firstName) { return bind<string, string>(spaces, [=](auto) { return bind<string, string>(letters, [=](auto lastName) { return pure<string>(mkHello(firstName, lastName)); }); }); }); ParserT<string> helloUsername = bind<string, string>(letters, [=](auto firstName) { return bind<string, string>(spaces, [=](auto) { return bind<string, string>(letters, [=](auto lastName) { return pure<string>(mkHello(firstName, lastName)); }); }); }); Monadic binding 42
  • 43. ParserT<string> helloUsername = bind<string, string>(letters, [=](auto firstName) { return bind<string, string>(spaces, [=](auto) { return bind<string, string>(letters, [=](auto lastName) { return pure<string>(mkHello(firstName, lastName)); }); }); }); ParserT<string> helloUsername = bind<string, string>(letters, [=](auto firstName) { return bind<string, string>(spaces, [=](auto) { return bind<string, string>(letters, [=](auto lastName) { return pure<string>(mkHello(firstName, lastName)); }); }); }); Monadic binding, reformatted 43
  • 44. ParserT<string> helloUsername = do { auto firstName <- letters; auto _ <- spaces; auto lastName <- letters; return pure<string>(mkHello(firstName, lastName)); }; Dear Santa, I was a good boy last year. Can I have?.. 44
  • 46. age integer first name string last name string salary float employee {35, “Jane”, “Street”, 54321} address {35, “Jane”, “Street”, 54321} house integer title string post index integer type string 46
  • 47. struct Employee { int age; string firstName; string lastName; double salary; }; 47 struct Address { int house; string title; string name; int postIndex; }; Algebraic Data Type
  • 48. struct Employee { int age; string firstName; string lastName; double salary; }; 48 struct Address { int house; string title; string name; int postIndex; }; using LogEntry = std::variant<Employee, Address>; Algebraic Data Type
  • 49. struct Employee { int age; string firstName; string lastName; double salary; }; 49 struct Address { int house; string title; string name; int postIndex; }; using LogEntry = std::variant<Employee, Address>; function<LogEntry(int a, const string& fn, const string& ln, double s)> mkEmployeeEntry; function<LogEntry(int h, const string& ttl, const string& n, int idx)> mkAddressEntry; Algebraic Data Type
  • 50. struct Config { string currentEntry; }; ParserT<Config, string> logToken = lit("employee") | lit("address"); ParserT<Config, Unit> setEntry = bind<string, Unit>( logToken, [](const string& s) { return putSt(Config { s }); }); Putting state 50
  • 51. struct Config { string currentEntry; }; ParserT<Config, string> logToken = lit("employee") | lit("address"); ParserT<Config, Unit> setEntry = bind<string, Unit>( logToken, [](const string& s) { return putSt(Config { s }); }); Putting state 51
  • 52. ParserT<Config, LogEntry> logEntry = bind<Config, LogEntry>(getSt, [=](Config cfg) { if (cfg.currentEntry == "employee") return fmap(mkEmployeeEntry, employeeParser); return fmap(mkAddressEntry, addressParser); }); Getting state 52
  • 53. ParserT<Config, LogEntry> logEntry = bind<Config, LogEntry>(getSt, [=](Config cfg) { if (cfg.currentEntry == "employee") return fmap(mkEmployeeEntry, employeeParser); return fmap(mkAddressEntry, addressParser); }); Getting state 53
  • 55. Monadic parser combinators ● Monad: do-notation, bind, when, unless, sequence, mapM, guard ● Applicative: app, pure ● Alternative: alt, operator| ● Functor: fmap ● Time travelling: lookForward, lookBackward ● State handling: getSt, putSt ● Error handling: tryP, safeP, onFail, onSuccess, failWith 55
  • 56. 56 GitHub List: Functional Programming in C++ https://github.com/graninas/cpp_functional_programming�� ● Books ● Articles ● Papers ● Talks ● QA ● Libraries ● Showcase projects
  • 57. Thanks for watching! Alexander Granin graninas@gmail.com Twitter: @graninas C++ Russia 2019, Moscow 57