occi 2.0.6 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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