occi 2.0.6 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/.gitignore +1 -0
  2. data/.yardopts +1 -1
  3. data/Gemfile +3 -20
  4. data/Gemfile.lock +10 -59
  5. data/README.md +64 -2
  6. data/etc/model/infrastructure/compute.json +115 -0
  7. data/etc/model/infrastructure/ipnetwork.json +43 -0
  8. data/etc/model/infrastructure/ipnetworkinterface.json +43 -0
  9. data/etc/model/infrastructure/network.json +56 -0
  10. data/etc/model/infrastructure/networkinterface.json +40 -0
  11. data/etc/model/infrastructure/os_template.json +9 -0
  12. data/etc/model/infrastructure/resource_template.json +9 -0
  13. data/etc/model/infrastructure/storage.json +75 -0
  14. data/etc/model/infrastructure/storagelink.json +38 -0
  15. data/lib/occi/collection.rb +34 -0
  16. data/lib/occi/core/action.rb +0 -21
  17. data/lib/occi/core/attribute_properties.rb +0 -21
  18. data/lib/occi/core/attributes.rb +1 -20
  19. data/lib/occi/core/category.rb +0 -21
  20. data/lib/occi/core/entity.rb +7 -28
  21. data/lib/occi/core/kind.rb +1 -22
  22. data/lib/occi/core/link.rb +3 -23
  23. data/lib/occi/core/mixin.rb +0 -22
  24. data/lib/occi/core/resource.rb +3 -24
  25. data/lib/occi/log.rb +24 -22
  26. data/lib/occi/model.rb +102 -0
  27. data/lib/occi/{parse.rb → parser.rb} +73 -56
  28. data/lib/occi/version.rb +1 -1
  29. data/lib/occi.rb +17 -17
  30. data/lib/{occi/antlr → occiantlr}/.gitignore +0 -0
  31. data/lib/{occi/antlr/OCCI.g → occiantlr/OCCIANTLR.g} +17 -50
  32. data/lib/{occi/antlr/OCCI.tokens → occiantlr/OCCIANTLR.tokens} +4 -2
  33. data/lib/{occi/antlr/OCCILexer.rb → occiantlr/OCCIANTLRLexer.rb} +597 -555
  34. data/lib/occiantlr/OCCIANTLRParser.rb +2232 -0
  35. data/lib/{occi/antlr → occiantlr}/README.md +0 -0
  36. data/occi.gemspec +3 -0
  37. data/spec/occi/collection_spec.rb +19 -0
  38. data/spec/occi/log_spec.rb +16 -0
  39. data/spec/occi/model_spec.rb +26 -0
  40. data/spec/occi/parser_spec.rb +12 -0
  41. data/spec/occiantlr/parser_spec.rb +84 -0
  42. metadata +78 -14
  43. data/lib/occi/antlr/OCCIParser.rb +0 -2472
  44. data/lib/occi/core/collection.rb +0 -27
  45. data/lib/occi/exceptions.rb +0 -59
  46. data/lib/occi/registry.rb +0 -87
  47. data/spec/occi/antlr/parser_spec.rb +0 -82
@@ -1,32 +1,12 @@
1
- ##############################################################################
2
- # Copyright 2011 Service Computing group, TU Dortmund
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- ##############################################################################
16
-
17
- ##############################################################################
18
- # @note OCCI RESTful Web Service
19
- # @author Florian Feldhaus, Piotr Kasprzak
20
- ##############################################################################
21
-
22
1
  require 'json'
23
- #require 'nokogiri'
24
- require 'occi/core/collection'
2
+ require 'nokogiri'
3
+ require 'hashie/mash'
4
+ require 'occi/collection'
25
5
  require 'occi/log'
26
- require 'occi/antlr/OCCIParser'
6
+ require 'occiantlr/OCCIANTLRParser'
27
7
 
28
8
  module OCCI
29
- class Parse
9
+ class Parser
30
10
 
31
11
  =begin
32
12
  if content_type.includes?('multipart')
@@ -54,16 +34,49 @@ module OCCI
54
34
  end
55
35
  =end
56
36
 
37
+ # Parses an OCCI message and extracts OCCI relevant information
38
+ # @param [String] media_type the media type of the OCCI message
39
+ # @param [String] body the body of the OCCI message
40
+ # @param [true, false] category for text/plain and text/occi media types information e.g. from the HTTP request location is needed to determine if the OCCI message includes a category or an entity
41
+ # @param [Hash] header optional header of the OCCI message
42
+ # @return [Array<Array, OCCI::Core::Collection>] list consisting of an array of locations and the OCCI object collection
43
+ def self.parse(media_type, body, category=false, header={ })
44
+ OCCI::Log.debug('### Parsing request data to OCCI data structure ###')
45
+ collection = OCCI::Collection.new
46
+ # always check header for locations
47
+ locations = self.header_locations(header)
48
+ category ? collection = self.header_categories(header) : collection = self.header_entity(header) if locations.empty?
49
+
50
+ case media_type
51
+ when 'text/uri-list'
52
+ body.each_line { |line| locations << URI.parse(line) }
53
+ when 'text/plain', nil
54
+ locations = self.text_locations(body)
55
+ category ? collection = self.text_categories(body) : collection = self.text_entity(body) if locations.empty?
56
+ when 'application/occi+json', 'application/json'
57
+ collection = self.json(body)
58
+ when 'application/occi+xml', 'application/xml'
59
+ collection = self.xml(body)
60
+ #when 'application/ovf+xml'
61
+ # collection = self.ovf(body)
62
+ else
63
+ raise OCCI::ContentTypeNotSupported
64
+ end
65
+ return locations, collection
66
+ end
67
+
68
+ private
69
+
57
70
  def self.header_locations(header)
58
71
  x_occi_location_strings = header['HTTP_X_OCCI_LOCATION'].to_s.split(',')
59
- x_occi_location_strings.collect { |loc| OCCI::Parser.new('X-OCCI-Location: ' + loc).x_occi_location }
72
+ x_occi_location_strings.collect { |loc| OCCIANTLR::Parser.new('X-OCCI-Location: ' + loc).x_occi_location }
60
73
  end
61
74
 
62
75
  def self.header_categories(header)
63
- collection = OCCI::Core::Collection.new
76
+ collection = OCCI::Core::Collection.new
64
77
  category_strings = header['HTTP_CATEGORY'].to_s.split(',')
65
78
  category_strings.each do |cat|
66
- category = OCCI::Parser.new('Category: ' + cat).category
79
+ category = OCCIANTLR::Parser.new('Category: ' + cat).category
67
80
  collection.kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) }
68
81
  collection.mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) }
69
82
  collection.actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) }
@@ -72,18 +85,18 @@ module OCCI
72
85
  end
73
86
 
74
87
  def self.header_entity(header)
75
- collection = OCCI::Core::Collection.new
76
- entity = Hashie::Mash.new
88
+ collection = OCCI::Collection.new
89
+ entity = Hashie::Mash.new
77
90
  category_strings = header['HTTP_CATEGORY'].to_s.split(',')
78
91
  return collection if category_strings.empty?
79
92
  attribute_strings = header['HTTP_X_OCCI_ATTRIBUTE'].to_s.split(',')
80
- categories = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []})
81
- category_strings.each { |cat| categories.merge!(OCCI::Parser.new('Category: ' + cat).category) }
93
+ categories = Hashie::Mash.new({ :kinds => [], :mixins => [], :actions => [] })
94
+ category_strings.each { |cat| categories.merge!(OCCIANTLR::Parser.new('Category: ' + cat).category) }
82
95
  return collection if categories.kinds.empty?
83
96
  entity.kind = categories.kinds.first.scheme + categories.kinds.first.term
84
97
  entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if categories.mixins.any?
85
- attribute_strings.each { |attr| entity.attributes!.merge!(OCCI::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute) }
86
- kind = OCCI::Registry.get_by_id(entity.kind)
98
+ attribute_strings.each { |attr| entity.attributes!.merge!(OCCIANTLR::Parser.new('X-OCCI-Attribute: ' + attr).x_occi_attribute) }
99
+ kind = OCCI::Model.get_by_id(entity.kind)
87
100
  # TODO: error handling
88
101
  return collection if kind.nil?
89
102
  if kind.entity_type == OCCI::Core::Link.name
@@ -92,20 +105,20 @@ module OCCI
92
105
  collection.links << OCCI::Core::Link.new(entity)
93
106
  elsif kind.entity_type == OCCI::Core::Resource.name
94
107
  link_strings = header['HTTP_LINK'].to_s.split(',')
95
- link_strings.each { |link| entity.links << OCCI::Parser.new('Link: ' + link).link }
108
+ link_strings.each { |link| entity.links << OCCIANTLR::Parser.new('Link: ' + link).link }
96
109
  collection.resources << OCCI::Core::Resource.new(entity)
97
110
  end
98
111
  collection
99
112
  end
100
113
 
101
114
  def self.text_locations(text)
102
- text.lines.collect { |line| OCCI::Parser.new(line).x_occi_location if line.include? 'X-OCCI-Location' }.compact
115
+ text.lines.collect { |line| OCCIANTLR::Parser.new(line).x_occi_location if line.include? 'X-OCCI-Location' }.compact
103
116
  end
104
117
 
105
118
  def self.text_categories(text)
106
119
  collection = OCCI::Core::Collection.new
107
120
  text.each_line do |line|
108
- category = OCCI::Parser.new(line).category
121
+ category = OCCIANTLR::Parser.new(line).category
109
122
  collection.kinds.concat category.kinds.collect { |kind| OCCI::Core::Kind.new(kind) }
110
123
  collection.mixins.concat category.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) }
111
124
  collection.actions.concat category.actions.collect { |action| OCCI::Core::Action.new(action) }
@@ -114,25 +127,25 @@ module OCCI
114
127
  end
115
128
 
116
129
  def self.text_entity(text)
117
- collection = OCCI::Core::Collection.new
118
- entity = Hashie::Mash.new
119
- links = []
120
- categories = Hashie::Mash.new({:kinds => [], :mixins => [], :actions => []})
130
+ collection = OCCI::Collection.new
131
+ entity = Hashie::Mash.new
132
+ links = []
133
+ categories = Hashie::Mash.new({ :kinds => [], :mixins => [], :actions => [] })
121
134
  text.each_line do |line|
122
- categories.merge!(OCCI::Parser.new(line).category) if line.include? 'Category'
123
- entity.attributes!.merge!(OCCI::Parser.new(line).x_occi_attribute) if line.include? 'X-OCCI-Attribute'
124
- links << OCCI::Parser.new(line).link if line.include? 'Link'
135
+ categories.merge!(OCCIANTLR::Parser.new(line).category) if line.include? 'Category'
136
+ entity.attributes!.merge!(OCCIANTLR::Parser.new(line).x_occi_attribute) if line.include? 'X-OCCI-Attribute'
137
+ links << OCCIANTLR::Parser.new(line).link if line.include? 'Link'
125
138
  end
126
139
  entity.kind = categories.kinds.first.scheme + categories.kinds.first.term if categories.kinds.first
127
140
  entity.mixins = categories.mixins.collect { |mixin| mixin.scheme + mixin.term } if entity.mixins
128
- kind = OCCI::Registry.get_by_id(entity.kind)
141
+ kind = OCCI::Model.get_by_id(entity.kind)
129
142
  # TODO: error handling
130
143
  return collection if kind.nil?
131
- if OCCI::Registry.get_by_id(entity.kind).entity_type == OCCI::Core::Link.name
144
+ if OCCI::Model.get_by_id(entity.kind).entity_type == OCCI::Core::Link.name
132
145
  entity.target = links.first.attributes.occi!.core!.target
133
146
  entity.source = links.first.attributes.occi!.core!.source
134
147
  collection.links << OCCI::Core::Link.new(entity)
135
- elsif OCCI::Registry.get_by_id(entity.kind).entity_type == OCCI::Core::Resource.name
148
+ elsif OCCI::Model.get_by_id(entity.kind).entity_type == OCCI::Core::Resource.name
136
149
  entity.links = links
137
150
  collection.resources << OCCI::Core::Resource.new(entity)
138
151
  end unless entity.kind.nil?
@@ -141,7 +154,17 @@ module OCCI
141
154
 
142
155
  def self.json(json)
143
156
  collection = OCCI::Core::Collection.new
144
- hash = Hashie::Mash.new(JSON.parse(json))
157
+ hash = Hashie::Mash.new(JSON.parse(json))
158
+ collection.kinds.concat hash.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } if hash.kinds
159
+ collection.mixins.concat hash.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } if hash.mixins
160
+ collection.resources.concat hash.resources.collect { |resource| OCCI::Core::Resource.new(resource) } if hash.resources
161
+ collection.links.concat hash.links.collect { |link| OCCI::Core::Link.new(link) } if hash.links
162
+ collection
163
+ end
164
+
165
+ def self.xml(xml)
166
+ collection = OCCI::Collection.new
167
+ hash = Hashie::Mash.new(Hash.from_xml(Nokogiri::XML(xml)))
145
168
  collection.kinds.concat hash.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } if hash.kinds
146
169
  collection.mixins.concat hash.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } if hash.mixins
147
170
  collection.resources.concat hash.resources.collect { |resource| OCCI::Core::Resource.new(resource) } if hash.resources
@@ -149,14 +172,8 @@ module OCCI
149
172
  collection
150
173
  end
151
174
 
152
- #def self.xml(xml)
153
- # collection = OCCI::Core::Collection.new
154
- # hash = Hashie::Mash.new(Hash.from_xml(Nokogiri::XML(xml)))
155
- # collection.kinds.concat hash.kinds.collect { |kind| OCCI::Core::Kind.new(kind) } if hash.kinds
156
- # collection.mixins.concat hash.mixins.collect { |mixin| OCCI::Core::Mixin.new(mixin) } if hash.mixins
157
- # collection.resources.concat hash.resources.collect { |resource| OCCI::Core::Resource.new(resource) } if hash.resources
158
- # collection.links.concat hash.links.collect { |link| OCCI::Core::Link.new(link) } if hash.links
159
- # collection
175
+ #def self.ovf(ovf)
176
+ # TODO: implement ovf / ova messages
160
177
  #end
161
178
 
162
179
  end
data/lib/occi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module OCCI
2
- VERSION = "2.0.6" unless defined?(::OCCI::VERSION)
2
+ VERSION = "2.1.0" unless defined?(::OCCI::VERSION)
3
3
  end
data/lib/occi.rb CHANGED
@@ -1,17 +1,17 @@
1
- module OCCI
2
- require 'occi/version'
3
- require 'occi/parse'
4
- require 'occi/registry'
5
- require 'occi/log'
6
- require 'occi/exceptions'
7
- require 'occi/core/action'
8
- require 'occi/core/attribute_properties'
9
- require 'occi/core/attributes'
10
- require 'occi/core/category'
11
- require 'occi/core/collection'
12
- require 'occi/core/entity'
13
- require 'occi/core/kind'
14
- require 'occi/core/link'
15
- require 'occi/core/mixin'
16
- require 'occi/core/resource'
17
- end
1
+ require 'occi/version'
2
+ require 'occi/parser'
3
+ require 'occi/model'
4
+ require 'occi/log'
5
+ require 'occi/collection'
6
+ require 'occi/core/action'
7
+ require 'occi/core/attribute_properties'
8
+ require 'occi/core/attributes'
9
+ require 'occi/core/category'
10
+ require 'occi/core/entity'
11
+ require 'occi/core/kind'
12
+ require 'occi/core/link'
13
+ require 'occi/core/mixin'
14
+ require 'occi/core/resource'
15
+
16
+ require 'occiantlr/OCCIANTLRLexer'
17
+ require 'occiantlr/OCCIANTLRParser'
File without changes
@@ -1,31 +1,4 @@
1
- /*
2
- Copyright (c) 2008-2011, Intel Performance Learning Solutions Ltd.
3
- All rights reserved.
4
-
5
- Redistribution and use in source and binary forms, with or without
6
- modification, are permitted provided that the following conditions are met:
7
- * Redistributions of source code must retain the above copyright
8
- notice, this list of conditions and the following disclaimer.
9
- * Redistributions in binary form must reproduce the above copyright
10
- notice, this list of conditions and the following disclaimer in the
11
- documentation and/or other materials provided with the distribution.
12
- * Neither the name of Intel Performance Learning Solutions Ltd. nor the
13
- names of its contributors may be used to endorse or promote products
14
- derived from this software without specific prior written permission.
15
-
16
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
- DISCLAIMED. IN NO EVENT SHALL Intel Performance Learning Solutions Ltd. BE LIABLE FOR ANY
20
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
- */
27
-
28
- grammar OCCI;
1
+ grammar OCCIANTLR;
29
2
 
30
3
  options {
31
4
  language = Ruby;
@@ -34,7 +7,7 @@ options {
34
7
  @header {
35
8
  require 'uri'
36
9
  require 'hashie'
37
- ATTRIBUTE = { :mutable => true, :required => false, :type => { :string => {} }, :default => '' }
10
+ ATTRIBUTE = { :mutable => true, :required => false, :type => "string" }
38
11
  }
39
12
 
40
13
  /*
@@ -73,16 +46,16 @@ category returns [hash]
73
46
  { value = $class_type.text };
74
47
  category_title returns [value] : ';' WS? 'title' '=' '"' title '"'
75
48
  { value = $title.text };
76
- category_rel returns [value] : ';' WS? 'rel' '=' '"' rel '"'
77
- { value = $rel.text };
78
- category_location returns [value] : ';' WS? 'location' '=' '"' location '"'
79
- { value = $location.text };
49
+ category_rel returns [value] : ';' WS? 'rel' '=' '"' uri '"'
50
+ { value = $uri.text };
51
+ category_location returns [value] : ';' WS? 'location' '=' '"' uri '"'
52
+ { value = $uri.text };
80
53
  category_attributes returns [hash] @init{hash = Hashie::Mash.new}
81
54
  : ';' WS? 'attributes' '=' '"' attr=attribute_name { hash.merge!($attr.hash) }
82
- ( WS? next_attr=attribute_name { hash.merge!($next_attr.hash) } )* '"';
55
+ ( WS next_attr=attribute_name { hash.merge!($next_attr.hash) } )* '"';
83
56
  category_actions returns [array] @init{array = Array.new}
84
- : ';' WS? 'actions' '=' '"' act=action_location { array << $act.text }
85
- ( WS? next_act=action_location { array << $next_act.text } )* '"';
57
+ : ';' WS? 'actions' '=' '"' act=uri { array << $act.text }
58
+ ( WS next_act=uri { array << $next_act.text } )* '"';
86
59
 
87
60
  /* e.g.
88
61
  Link:
@@ -104,10 +77,10 @@ link returns [hash]
104
77
  link_attributes { hash[:attributes] = $link_attributes.hash }
105
78
  ';'?
106
79
  ;
107
- link_target returns [value] : WS? '<' target '>' { value = $target.text };
108
- link_rel returns [value] : ';' WS? 'rel' '=' '"' rel '"' { value = $rel.text };
109
- link_self returns [value] : ';' WS? 'self' '=' '"' self_location '"' { value = $self_location.text };
110
- link_category returns [value] : ';' WS? 'category' '=' '"' category_name '"' { value = $category_name.text };
80
+ link_target returns [value] : WS? '<' uri '>' { value = $uri.text };
81
+ link_rel returns [value] : ';' WS? 'rel' '=' '"' uri '"' { value = $uri.text };
82
+ link_self returns [value] : ';' WS? 'self' '=' '"' uri '"' { value = $uri.text };
83
+ link_category returns [value] : ';' WS? 'category' '=' '"' uri '"' { value = $uri.text };
111
84
  link_attributes returns [hash] @init { hash = Hashie::Mash.new }
112
85
  : (';' WS? attribute { hash.merge!($attribute.hash) } )*;
113
86
 
@@ -130,16 +103,14 @@ X-OCCI-Location: http://example.com/compute/123
130
103
  X-OCCI-Location: http://example.com/compute/456
131
104
  */
132
105
 
133
- x_occi_location returns [uri]
134
- : 'X-OCCI-Location' ':' WS? location ';'? { uri = URI.parse($location.text) } ;
106
+ x_occi_location returns [location]
107
+ : 'X-OCCI-Location' ':' WS? uri ';'? { location = URI.parse($uri.text) } ;
135
108
 
136
- uri : ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' )+;
109
+ uri : ( LOALPHA | UPALPHA | DIGIT | '@' | ':' | '%' | '_' | '\\' | '+' | '.' | '~' | '#' | '?' | '&' | '/' | '=' | '-' | 'action' | 'kind' | 'mixin' | 'location' | 'attributes' | 'rel' | 'title' | 'actions' | 'scheme' | 'term' | 'category' | 'self' | 'Link' )+;
137
110
  term : LOALPHA ( LOALPHA | DIGIT | '-' | '_')*;
138
111
  scheme : uri;
139
112
  class_type : ( 'kind' | 'mixin' | 'action' );
140
113
  title : ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )*;
141
- rel : uri;
142
- location : uri;
143
114
  attribute returns [hash] @init { hash = Hashie::Mash.new }
144
115
  : comp_first=attribute_component { cur_hash = hash; comp = $comp_first.text }
145
116
  ( '.' comp_next=attribute_component { cur_hash[comp.to_sym] = Hashie::Mash.new; cur_hash = cur_hash[comp.to_sym]; comp = $comp_next.text })*
@@ -152,13 +123,9 @@ attribute_component : LOALPHA ( LOALPHA | DIGIT | '-' | '_' )*;
152
123
  attribute_value returns [value] : ( string { value = $string.text } | number { value = $number.text.to_i } );
153
124
  string : ( '"' ( ESC | ~( '\\' | '"' | '\'' ) | '\'' )* '"');
154
125
  number : ( DIGIT* ( '.' DIGIT+ )? );
155
- action_location : uri;
156
- target : uri;
157
- self_location : uri;
158
- category_name : uri;
159
126
 
160
127
  LOALPHA : ('a'..'z')+;
161
128
  UPALPHA : ('A'..'Z')+;
162
129
  DIGIT : ('0'..'9');
163
130
  WS : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+;
164
- ESC : '\\' ( '"' | '\'' );
131
+ ESC : '\\' ( '"' | '\'' );
@@ -5,8 +5,8 @@ T__26=26
5
5
  T__25=25
6
6
  T__24=24
7
7
  T__23=23
8
- T__22=22
9
8
  ESC=8
9
+ T__22=22
10
10
  T__21=21
11
11
  T__20=20
12
12
  T__9=9
@@ -26,6 +26,7 @@ T__42=42
26
26
  T__43=43
27
27
  T__40=40
28
28
  T__41=41
29
+ T__44=44
29
30
  T__30=30
30
31
  T__31=31
31
32
  T__32=32
@@ -60,9 +61,10 @@ T__39=39
60
61
  '"'=14
61
62
  'rel'=17
62
63
  'actions'=20
64
+ 'term'=43
63
65
  'location'=18
64
66
  'action'=40
65
- '\''=43
67
+ '\''=44
66
68
  '?'=36
67
69
  'title'=16
68
70
  'mixin'=42