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
250
2
Share
Parsing with Blocks
CocoaHeads Hamburg
Chris Eidhof | @chriseidhof
May 08, 2014
More Decks by Chris Eidhof | @chriseidhof
See All by Chris Eidhof | @chriseidhof
Dutch FP Day 2015
chriseidhof
2
400
Tiny Networking in Swift
chriseidhof
2
19k
Functional Swift - Brooklyn
chriseidhof
3
1.3k
Functional Swift - SF
chriseidhof
6
26k
Functional Swift
chriseidhof
6
1.3k
Functional Swift
chriseidhof
1
170
Functional Programming in Swift
chriseidhof
40
19k
Lighter View Controllers
chriseidhof
4
210
Practical Concurrent Programming
chriseidhof
4
290
Other Decks in Technology
See All in Technology
Azure Lifecycle with Copilot CLI
torumakabe
3
880
生成AI時代のエンジニア育成 変わる時代と変わらないコト
starfish719
0
3.8k
BigQuery × dbtでコスト削減した話
rightcode
0
140
インフラを Excel 管理していた組織が 3 ヶ月で IaC 化されるまで
geekplus_tech
3
190
サイバーフィジカル社会とは何か / What Is a Cyber-Physical Society?
ks91
PRO
0
190
研究開発部メンバーの働き⽅ / Sansan R&D Profile
sansan33
PRO
4
23k
自分のハンドルは自分で握れ! ― 自分のケイパビリティを増やし、メンバーのケイパビリティ獲得を支援する ― / Take the wheel yourself
takaking22
1
500
JEDAI in Osaka 2026イントロ
taka_aki
0
210
終盤で崩壊させないAI駆動開発
j5ik2o
2
2.1k
Introduction to Bill One Development Engineer
sansan33
PRO
0
410
Hello UUID
mimifuwacc
0
140
2026年、知っておくべき最新 サーバレスTips10選/serverless-10-tips
slsops
12
4.8k
Featured
See All Featured
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
510
Docker and Python
trallard
47
3.8k
Designing Experiences People Love
moore
143
24k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
64
53k
The Pragmatic Product Professional
lauravandoore
37
7.2k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
120
The World Runs on Bad Software
bkeepers
PRO
72
12k
Facilitating Awesome Meetings
lara
57
6.8k
Designing Powerful Visuals for Engaging Learning
tmiket
1
340
RailsConf 2023
tenderlove
30
1.4k
Being A Developer After 40
akosma
91
590k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
160
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