Skip to content

Commit

Permalink
Merge remote branch 'mike/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ghnatiuk committed Nov 13, 2010
2 parents 1d16bcc + 708ba7d commit ef5c020
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 28 deletions.
2 changes: 0 additions & 2 deletions presentation/bdd/01_slide.md

This file was deleted.

99 changes: 88 additions & 11 deletions presentation/bdd_with_ragel/01_slide.md
@@ -1,10 +1,10 @@
!SLIDE
# BDD with Ragel
!SLIDE bullets incremental
# BDD (or TDD, or software development, or whatever)
* with Ragel

!SLIDE bullets incremental
* Get Ragel parsing _something_
* There are no rules (RSpec, then Cucumber)
* Prove it
# Externalize Evidence of Operation
* Make assertions on the collected evidence

!SLIDE
* 1st passing test example (spec side-by-side w/ ragel)
Expand All @@ -22,17 +22,40 @@
* pretty_formatter.feature

!SLIDE bullets incremental
# Testing
.notes SUT
.notes Driving out behavior
# What the Tests Told Us
.notes Event based design of Gherkin came about out of need to easily test lexer
.notes Remember regex == state machine, so inherently event driven
.notes Acceptance: when Ragel finishes its work and the current state is not less than the final lexer state

* Externalize evidence of operation
* Test spy: SexpRecorder
* Parameterize the ctor with object that receives events
* Parameterize the Lexer's ctor with a listener
* (Dependency Injection)
* Compose listeners for flexibility and additional layers of responsibility
* Test using a Test Spy listener: SexpRecorder

!SLIDE small

@@@ Ruby
class Lexer
%%{
machine lexer;
action do_action {
# Send the appropriate messages to the listener
}
main := 'foo' $do_action;
}%%

def initialize(listener)
@listener = listener
%% write data;
end

def scan(text)
data = text.unpack("c*")

%% write init;
%% write exec;
end
end

!SLIDE
.notes We know not really sexps but annoying pedants is more fun than being correct
Expand Down Expand Up @@ -73,6 +96,60 @@
[:step, "Then", "a GUI must be the answer", 4]
]

!SLIDE smaller
# A Real Test

@@@ Ruby
it "should parse steps with inline py_string" do
scan("Given I have a string\n\"\"\"\nhello\nworld\n\"\"\"")
@listener.to_sexp.should == [
[:step, "Given ", "I have a string", 1],
[:py_string, "hello\nworld", 2],
[:eof]
]
end

!SLIDE smallest
# Cucumber
@@@ Cucumber
Given a Gherkin parser
When the following text is parsed:
"""
Feature: Advanced Lulzfinding Mechanism
Scenario: Monty Python
Given the following excerpt:
\"\"\"
WOMAN: Who are the Britons?
ARTHUR: Well, we all are. we're all Britons and I am your king.
WOMAN: I didn't know we had a king. I thought we were an autonomous
collective.
DENNIS: You're fooling yourself. We're living in a dictatorship.
A self-perpetuating autocracy in which the working classes--
WOMAN: Oh there you go, bringing class into it again.
DENNIS: That's what it's all about if only people would--
ARTHUR: Please, please good people. I am in haste. Who lives
in that castle?
\"\"\"
When I read it
Then I should be amused
"""
Then there should be no parse errors

!SLIDE small

@@@ Ruby
Given /^a Gherkin parser$/ do
@parser = Gherkin::Parser.new(@listener)
end

Given "the following text is parsed:" do |text|
@parser.parse(text)
end

Then "there should be no parse errors" do
@listener.errors.should == []
end

!SLIDE
* utf8_pack
* 1.8/1.9 and UTF8
4 changes: 2 additions & 2 deletions presentation/introduction/01_slide.md
Expand Up @@ -14,11 +14,11 @@
# Ragel
* A tool for building parsers...
* ...by specifying state machines...
* ...with regular expressions.
* ...in a regular language.

!SLIDE bullets incremental
# Some people, when confronted with a problem, think "I know, I'll use regular expressions."

!SLIDE center
# "Now they have two problems"
# "Now they have two problems."
![atreyu](atreyu.png)
2 changes: 1 addition & 1 deletion presentation/ragel_syntax/01_slide.md
Expand Up @@ -18,7 +18,7 @@
%%write exec;
end
end
*
*

!SLIDE bullets
@@@ Ruby
Expand Down
@@ -1,3 +1,6 @@
!SLIDE
# The Problems With Regular Expressions

!SLIDE
# Regular expressions are a syntax

Expand Down Expand Up @@ -27,33 +30,50 @@
!SLIDE small bullets incremental
# Semantic Failure, Syntactic Confusion
* Failures with regular expressions are usually _semantic_
* (This doesn't mean the syntax is good)
* Two causes of confusion
* (This doesn't mean the syntax is that great)

.notes The primary source is that, well, Regexen are confusing
.notes It's really easy to write some that are impossible to understand
.notes Ragel addresses some of the syntax difficulties (but not all)
.notes We'll get to that in a second, but the other cause is how we think about matching
!SLIDE bullets incremental
# Two causes of confusion:
* Syntax
* Metaphor

!SLIDE bullets
# Syntax
* Ragel makes it easier to visualize what is happening when things go wrong

* Character for character, few things produce complexity like a regular expression
* If only there were a way to visualize what it is they create...

!SLIDE
# Thinking About Matching
## What does it mean "to match"?
## What is doing the matching?

!SLIDE bullets incremental
# Statements You May Have Heard
* "I matched the string against the regex"
* "This regex is matching more than it should"
* "All I did was try to parse HTML with regexen, and now Cthulhu insists I bring him home to meet Mom."

!SLIDE
# REGULAR EXPRESSIONS DO NOT DO THE MATCHING
## There is no "there" there

!SLIDE
# "Oh my god you guys! My class definition retrieved a record from the database!"

!SLIDE
# Regular Expressions Are A Syntax For Specifying State Machines

!SLIDE bullets
# State Machines
* The regex characters are the _transitions_
* Characters in the regex are the _transitions_
* The characters of input are the _events_
* The _states_ are generated by the compiler
* The _states_ are determined by the compiler

!SLIDE
# Ragel converts expressions into a state machine that reads characters one at a time until it reaches the end of input

!SLIDE center bullets incremental
# Example: /abc/
* "a", "b" and "c" are named transitions
* ![abc](abc.png)

.notes Ragel converts a series of machines into a table-driven* FSM that reads bytes one at a time until it reaches the end of input
File renamed without changes
2 changes: 1 addition & 1 deletion presentation/showoff.json
@@ -1,7 +1,7 @@
{ "name": "Consuming Gherkin", "sections": [
{"section":"introduction"},
{"section":"regular_language"},
{"section":"ragel_syntax"},
{"section":"bdd"},
{"section":"bdd_with_ragel"},
{"section":"why_ragel"},
{"section":"when_ragel"},
Expand Down

0 comments on commit ef5c020

Please sign in to comment.