Forked from cjheath/Example Treetop grammar fragment
Created
September 28, 2010 06:03
-
-
Save gabehollombe/600494 to your computer and use it in GitHub Desktop.
Parsing a text file for Pivotal Tracker stories with Treetop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LabelOne LabelTwo | |
- feature one (description one) | |
- feature two (description two) | |
- feature three with multiline desc following | |
desc line 1 | |
desc line 2 | |
desc line 3 | |
[] chore one (chore desc one) | |
[] chore two with multiline desc | |
chore desc line 1 | |
chore desc line 2 | |
LabelThree | |
- feature four (desc for feature four) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe 'the pivotxt treetop grammar' do | |
before do | |
grammar = File.join(File.dirname(__FILE__), '..', 'lib', 'pivtxt.treetop') | |
Treetop.load grammar | |
@parser = PivtxtParser.new | |
@parser.consume_all_input = false | |
end | |
it 'parses an example stories file' do | |
stories_file = File.join(File.dirname(__FILE__), 'fixtures', 'pivotxt_stories.txt') | |
tree = @parser.parse(File.read(stories_file).to_s) | |
print "FAILURE REASON: " + @parser.failure_reason.to_s if ! tree | |
label_groups = tree.value | |
labels = label_groups.first[:labels] | |
labels.should include('LabelOne', 'LabelTwo') | |
stories = label_groups.first[:stories] | |
stories.length.should == 5 | |
stories[0][:title].value.should == "feature one " | |
stories[0][:description].value.should == "(description one)" | |
stories[0][:type].should == :feature | |
multi_line_desc = stories[2][:description].value | |
multi_line_desc.should include('desc line 1', 'desc line 2', 'desc line 3') | |
stories[3][:type].should == :chore | |
stories[3][:title].value.should == "chore one " | |
stories[3][:description].value.should == "(chore desc one)" | |
#next label group | |
stories = label_groups[1][:stories] | |
stories.length.should == 1 | |
label_groups[1][:labels].should include('LabelThree') | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
grammar Pivtxt | |
rule label_groups | |
labeled_stories* | |
{ | |
def value | |
elements.collect{|e| e.value} | |
end | |
} | |
end | |
rule labeled_stories | |
blank_line* | |
labels:(one_line "\n") | |
stories | |
{ | |
def value | |
{ :labels => labels.text_value.split(' '), | |
:stories => stories.stories_array | |
} | |
end | |
} | |
end | |
rule stories | |
story* | |
{ | |
def stories_array | |
elements.collect {|e| e.value} | |
end | |
} | |
end | |
rule story | |
blank_line* | |
item:(feature / chore) | |
{ | |
def value | |
item.value | |
end | |
} | |
end | |
rule feature | |
indent '- ' | |
story_body | |
{ | |
def value | |
{:type => :feature, :title => story_body.title, :description => story_body.description} | |
end | |
} | |
end | |
rule chore | |
indent '[] ' | |
story_body | |
{ | |
def value | |
{:type => :chore, :title => story_body.title, :description => story_body.description} | |
end | |
} | |
end | |
rule story_body | |
title | |
description:( | |
"\n" multiline_description { def value; multiline_description.value; end } | |
/ | |
inline_description "\n" { def value; inline_description.value; end } | |
) | |
end | |
rule title | |
plain_text { | |
def value | |
text_value | |
end | |
} | |
end | |
rule inline_description | |
( | |
'(' inline_description ')' | |
/ | |
plain_text | |
) | |
{ | |
def value | |
text_value | |
end | |
} | |
end | |
rule multiline_description | |
(indent indent one_line "\n")* | |
{ | |
def value | |
text_value | |
end | |
} | |
end | |
#========================================== | |
# Utility rules | |
#========================================== | |
rule plain_text | |
(!non_plain .)* | |
end | |
# Characters not allowed in a one-line text fragment | |
rule non_plain | |
([()] / "\n") | |
end | |
# Any text to end of line: | |
rule one_line | |
(!"\n" .)* | |
end | |
rule blank_line | |
[ \t]* "\n" | |
end | |
rule indent | |
' ' | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment