Skip to content

Instantly share code, notes, and snippets.

@NilsHaldenwang
Created September 13, 2010 17:26
Show Gist options
  • Save NilsHaldenwang/577676 to your computer and use it in GitHub Desktop.
Save NilsHaldenwang/577676 to your computer and use it in GitHub Desktop.
grammar ERDL
rule rel_def_block
space 'Relationships' space '{' rel_def_seq '}' space <RelationShipBlockNode>
end
rule rel_def_seq
(relationship_definition)+ <RelationShipDefinitionSequenceNode>
end
rule relationship_definition
space entity space operator space entity space <RelationShipDefinitionNode>
end
rule operator
op_sym attrib_list? <OperatorNode>
end
rule op_sym
"=>" <HasMany>
/
"<=>" <HasAndBelongsToMany>
/
"->" <HasOne>
end
rule entity
[A-Za-z]* <EntityNode>
end
rule attrib_list
"(" space attrib ("," space attrib)* space ")" <AttributeList>
end
rule attrib
attrib_key ":" space attrib_val <Attribute>
end
rule attrib_key
[a-z]+ <AttribKey>
end
rule attrib_val
[a-zA-Z0-9]+ <AttribVal>
end
rule space
[\r\n\s\t]* <OptionalSpaceNode>
end
rule req_space
[\r\n\s\t]+ <RequiredSpaceNode>
end
end
class Treetop::Runtime::SyntaxNode
# Removes anonymous SyntaxNodes and OptionalSpaceNodes.
def preprocess
remove_class(Treetop::Runtime::SyntaxNode)
remove_class(OptionalSpaceNode)
elements.each { |e| e.preprocess } if !elements.nil?
end
def remove_class(klass)
elements.reject { |e| elements.delete e if e.class == klass } if !elements.nil?
end
def dump_elements
elements.each_with_index { |e, idx| puts "index: " << idx.to_s << " value: " << e.text_value } if !elements.nil?
end
# Finds all nodes of given class in a subtree and returns them
def find_nodes(klass)
if !elements.nil?
nodes = []
elements.each do |e|
nodes << e if e.class == klass
subnodes = e.find_nodes(klass)
(nodes = nodes + subnodes) if !subnodes.nil?
end
return nodes
end
nil
end
end
class RelationShipDefinitionNode < Treetop::Runtime::SyntaxNode
end
class EntityNode < Treetop::Runtime::SyntaxNode
end
class HasAndBelongsToMany < Treetop::Runtime::SyntaxNode
end
class HasMany < Treetop::Runtime::SyntaxNode
end
class HasOne < Treetop::Runtime::SyntaxNode
end
class OperatorNode < Treetop::Runtime::SyntaxNode
end
class RelationShipDefinitionSequenceNode < Treetop::Runtime::SyntaxNode
end
class OptionalSpaceNode < Treetop::Runtime::SyntaxNode
end
class RelationShipBlockNode < Treetop::Runtime::SyntaxNode
end
class RequiredSpaceNode < Treetop::Runtime::SyntaxNode
end
class AttributeList < Treetop::Runtime::SyntaxNode
# pull Attributes to upper lvl before going on with preprocessing
def preprocess
find_nodes(Attribute).each { |t| elements << t if(!t.nil? && !elements.include?(t))}
super
end
end
class Attribute < Treetop::Runtime::SyntaxNode
end
class AttribKey < Treetop::Runtime::SyntaxNode
end
class AttribVal < Treetop::Runtime::SyntaxNode
end
require 'rubygems'
require 'treetop'
require './nodes'
Treetop.load "grammars/ERDL"
parser = ERDLParser.new
rel_def_block = <<DEF
Relationships {
User =>(through: bla, as: blubber) Post
User -> Group
User <=> User
}
DEF
res = parser.parse(rel_def_block)
if res
puts "Success."
puts res.inspect
res.preprocess
puts
puts "########## Cleaned ##########"
puts
puts res.inspect
else
puts "ParseError:"
puts " " << parser.failure_reason
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment