Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Parsing with Blocks
Search
Chris Eidhof | @chriseidhof
May 08, 2014
Technology
2
220
Parsing with Blocks
CocoaHeads Hamburg
Chris Eidhof | @chriseidhof
May 08, 2014
Tweet
Share
More Decks by Chris Eidhof | @chriseidhof
See All by Chris Eidhof | @chriseidhof
Dutch FP Day 2015
chriseidhof
2
370
Tiny Networking in Swift
chriseidhof
2
19k
Functional Swift - Brooklyn
chriseidhof
3
1.2k
Functional Swift - SF
chriseidhof
6
26k
Functional Swift
chriseidhof
6
1.2k
Functional Swift
chriseidhof
1
140
Functional Programming in Swift
chriseidhof
40
19k
Lighter View Controllers
chriseidhof
4
190
Practical Concurrent Programming
chriseidhof
4
260
Other Decks in Technology
See All in Technology
TypeScriptの次なる大進化なるか!? 条件型を返り値とする関数の型推論
uhyo
2
1.7k
オープンソースAIとは何か? --「オープンソースAIの定義 v1.0」詳細解説
shujisado
10
1.2k
【Startup CTO of the Year 2024 / Audience Award】アセンド取締役CTO 丹羽健
niwatakeru
0
1.3k
Introduction to Works of ML Engineer in LY Corporation
lycorp_recruit_jp
0
140
SREが投資するAIOps ~ペアーズにおけるLLM for Developerへの取り組み~
takumiogawa
1
440
AWS Media Services 最新サービスアップデート 2024
eijikominami
0
200
Lambda10周年!Lambdaは何をもたらしたか
smt7174
2
110
OCI Network Firewall 概要
oracle4engineer
PRO
0
4.2k
個人でもIAM Identity Centerを使おう!(アクセス管理編)
ryder472
4
230
開発生産性を上げながらビジネスも30倍成長させてきたチームの姿
kamina_zzz
2
1.7k
TypeScript、上達の瞬間
sadnessojisan
46
13k
OS 標準のデザインシステムを超えて - より柔軟な Flutter テーマ管理 | FlutterKaigi 2024
ronnnnn
1
250
Featured
See All Featured
YesSQL, Process and Tooling at Scale
rocio
169
14k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Side Projects
sachag
452
42k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
430
KATA
mclloyd
29
14k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Teambox: Starting and Learning
jrom
133
8.8k
Building an army of robots
kneath
302
43k
The Cult of Friendly URLs
andyhume
78
6k
Transcript
Parsing with Blocks CocoaHeads Hamburg Chris Eidhof
Warning All of this is a bit crazy
Building languages is magical
stylesheet { multiplier = if(slide.onlyHeader, 2, 1), baseFontSize = 45
* multiplier, splitBaseFontSize = 25, backgroundColor = colorScheme.backgroundColor, bodyFont = { family = "Apercu", color = colorScheme.textColor, size = baseFontSize } }
DSLs → SQL → AutoLayout → NSPredicate → Regular Expressions
→ ActiveRecord
DSLs External vs. Internal
DSLs: External → SQL → CSS → NSPredicate format syntax
DSLs: Internal [view1 mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(superview.mas_top).with.offset(padding.top); make.left.equalTo(superview.mas_left).with.offset(padding.left); make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom); make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}] Source: Masonry
V:[topField]-10-[bottomField] [flexibleButton(>=70,<=100)] |-[find]-[findNext]-[findField(>=20)]-|
None
Building an external DSL
None
Parsing 1. String → Stream of tokens 2. Stream of
tokens → Syntax Tree 3. Interpret Syntax Tree
Existing approaches → Hand-rolled parsers → Parser generators → ParseKit
/ CoreParse
An alternative approach → Based on functional programming → Backtracking
→ Immutable objects
The language
1 + 2 * 3 Expr ← Sum Sum ←
Product '+' Product Product ← Atom '*' Atom Atom ← Number
1 + 2 * 3 Expr ← Sum Sum ←
Product '+' Product | Product Product ← Atom '*' Atom | Atom Atom ← Number
(1 + 2) * 3
(1 + 2) * 3 Expr ← Sum Sum ←
Product '+' Product | Product Product ← Atom '*' Atom | Atom Atom ← Number | '(' Expr ')'
Block Syntax returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...}; Source: http://goshdarnblocksyntax.com
Live Coding
A stylesheet language
stylesheet { multiplier = if(slide.onlyHeader, 2, 1), baseFontSize = 45
* multiplier, splitBaseFontSize = 25, backgroundColor = colorScheme.backgroundColor, bodyFont = { family = "Apercu", color = colorScheme.textColor, size = baseFontSize } }
Rule stylesheet = ^(State *p) { __block NSArray *functions =
nil; return p.identifier().token(@"{"). manySepBy(method, comma).bind(to(functions)). token(@"}").yield(^id { return [[StylesheetObject alloc] initWithFunctions:functions]; }); };
Rule method = ^(State * p) { __block NSString* name
= nil; __block id body= nil; __block NSArray *parameters = nil; return p.identifier().bind(to(name)). optional(parameterList).bind(to(parameters)). token(@"="). rule(self.expression).bind(to(body)). yield(^id { return [[StylesheetFunction alloc] initWithName:name body:body parameters:parameters]; }); };
Rule mulExpression = infix(@"*", infix(@"/", functionCallExpression)); Rule addExpression = infix(@"+",
infix(@"-", mulExpression));
API
typedef State *(^Rule)(State *p);
@interface State : NSObject @property (nonatomic, strong) id result; @property
(nonatomic) BOOL failed; @property (nonatomic) NSString *errorMessage; @property (nonatomic) State *(^token)(NSString *); @property (nonatomic) State *(^identifier)(); @property (nonatomic) State *(^yield)(id (^)()); @property (nonatomic) State *(^bind)(void(^)(id result)); @property (nonatomic) State *(^oneOf)(NSArray *); @property (nonatomic) State *(^optional)(Rule); @property (nonatomic) State *(^eof)(); @property (nonatomic) State *(^rule)(Rule); @end
State Internals @interface State () @property (nonatomic) NSArray *tokens; @property
(nonatomic) NSUInteger tokenIndex; @end
self.token = ^(NSString* token) { if (self.failed) return self; NSString*
peek = self.peek; if ([token isEqual:peek]) { return [self next:peek]; } else { NSString* msg = [NSString stringWithFormat:@"Expected '%@', saw '%@'", token, peek]; return [self fail:msg]; } };
- (State *)next:(id)result { if (self.failed) return self; State *next
= [self copy]; next.failed = NO; next.result = result; next.tokenIndex++; return next; }
We created two DSLs → One for parsing (embedded) →
One external https://github.com/chriseidhof/parsingwithblocks
Thanks → @chriseidhof → http://www.objc.io → http://www.uikonf.com → http://www.decksetapp.com