Created
September 13, 2010 17:26
-
-
Save NilsHaldenwang/577676 to your computer and use it in GitHub Desktop.
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 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 |
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
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 |
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
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