rip-parser 0.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 (80) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +15 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.md +9 -0
  8. data/README.md +13 -0
  9. data/Rakefile +1 -0
  10. data/bin/console +8 -0
  11. data/bin/setup +8 -0
  12. data/legacy/normalizer.rb +279 -0
  13. data/legacy/parser_spec.rb +999 -0
  14. data/legacy/rules.rb +250 -0
  15. data/legacy/rules_spec.rb +1700 -0
  16. data/rip-parser.gemspec +20 -0
  17. data/source/rip/parser/about.rb +9 -0
  18. data/source/rip/parser/error.rb +36 -0
  19. data/source/rip/parser/grammar.rb +23 -0
  20. data/source/rip/parser/keywords.rb +84 -0
  21. data/source/rip/parser/location.rb +47 -0
  22. data/source/rip/parser/node.rb +115 -0
  23. data/source/rip/parser/rules/assignment.rb +23 -0
  24. data/source/rip/parser/rules/binary_condition.rb +24 -0
  25. data/source/rip/parser/rules/character.rb +40 -0
  26. data/source/rip/parser/rules/class.rb +60 -0
  27. data/source/rip/parser/rules/common.rb +47 -0
  28. data/source/rip/parser/rules/date_time.rb +31 -0
  29. data/source/rip/parser/rules/expression.rb +122 -0
  30. data/source/rip/parser/rules/import.rb +23 -0
  31. data/source/rip/parser/rules/invocation.rb +15 -0
  32. data/source/rip/parser/rules/invocation_index.rb +15 -0
  33. data/source/rip/parser/rules/keyword.rb +12 -0
  34. data/source/rip/parser/rules/lambda.rb +45 -0
  35. data/source/rip/parser/rules/list.rb +18 -0
  36. data/source/rip/parser/rules/map.rb +15 -0
  37. data/source/rip/parser/rules/module.rb +29 -0
  38. data/source/rip/parser/rules/number.rb +21 -0
  39. data/source/rip/parser/rules/pair.rb +13 -0
  40. data/source/rip/parser/rules/property.rb +33 -0
  41. data/source/rip/parser/rules/range.rb +15 -0
  42. data/source/rip/parser/rules/reference.rb +16 -0
  43. data/source/rip/parser/rules/string.rb +41 -0
  44. data/source/rip/parser/rules/unit.rb +17 -0
  45. data/source/rip/parser/rules.rb +7 -0
  46. data/source/rip/parser/utilities/normalizer.rb +638 -0
  47. data/source/rip/parser.rb +24 -0
  48. data/source/rip-parser.rb +1 -0
  49. data/spec/fixtures/syntax_sample.rip +96 -0
  50. data/spec/spec_helper.rb +20 -0
  51. data/spec/support/helpers.rb +57 -0
  52. data/spec/support/parslet.rb +1 -0
  53. data/spec/support/shared_examples.rb +9 -0
  54. data/spec/unit/rip/parser/grammar_spec.rb +8 -0
  55. data/spec/unit/rip/parser/location_spec.rb +89 -0
  56. data/spec/unit/rip/parser/node_spec.rb +157 -0
  57. data/spec/unit/rip/parser/rules/assignment_spec.rb +59 -0
  58. data/spec/unit/rip/parser/rules/binary_condition_spec.rb +41 -0
  59. data/spec/unit/rip/parser/rules/character_spec.rb +29 -0
  60. data/spec/unit/rip/parser/rules/class_spec.rb +181 -0
  61. data/spec/unit/rip/parser/rules/common_spec.rb +88 -0
  62. data/spec/unit/rip/parser/rules/date_time_spec.rb +61 -0
  63. data/spec/unit/rip/parser/rules/expression_spec.rb +95 -0
  64. data/spec/unit/rip/parser/rules/import_spec.rb +64 -0
  65. data/spec/unit/rip/parser/rules/invocation_index_spec.rb +46 -0
  66. data/spec/unit/rip/parser/rules/invocation_spec.rb +46 -0
  67. data/spec/unit/rip/parser/rules/keyword_spec.rb +17 -0
  68. data/spec/unit/rip/parser/rules/lambda_spec.rb +174 -0
  69. data/spec/unit/rip/parser/rules/list_spec.rb +45 -0
  70. data/spec/unit/rip/parser/rules/map_spec.rb +36 -0
  71. data/spec/unit/rip/parser/rules/module_spec.rb +63 -0
  72. data/spec/unit/rip/parser/rules/number_spec.rb +40 -0
  73. data/spec/unit/rip/parser/rules/pair_spec.rb +25 -0
  74. data/spec/unit/rip/parser/rules/property_spec.rb +27 -0
  75. data/spec/unit/rip/parser/rules/range_spec.rb +37 -0
  76. data/spec/unit/rip/parser/rules/reference_spec.rb +43 -0
  77. data/spec/unit/rip/parser/rules/string_spec.rb +166 -0
  78. data/spec/unit/rip/parser/rules/unit_spec.rb +17 -0
  79. data/spec/unit/rip/parser_spec.rb +106 -0
  80. metadata +192 -0
@@ -0,0 +1,20 @@
1
+ require_relative './source/rip/parser/about'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'rip-parser'
5
+ spec.version = Rip::Parser::About.version
6
+ spec.author = 'Thomas Ingram'
7
+ spec.license = 'MIT'
8
+ spec.summary = 'Composable parser for Rip'
9
+ spec.homepage = 'http://www.rip-lang.org/'
10
+
11
+ spec.files = `git ls-files -z`.split("\x0")
12
+ spec.require_paths = [ 'source' ]
13
+
14
+ spec.add_runtime_dependency 'parslet', '~> 1.7.0'
15
+
16
+ spec.add_development_dependency 'pry'
17
+ spec.add_development_dependency 'pry-doc'
18
+ spec.add_development_dependency 'rake'
19
+ spec.add_development_dependency 'rspec'
20
+ end
@@ -0,0 +1,9 @@
1
+ module Rip
2
+ module Parser
3
+ module About
4
+ def self.version
5
+ '0.1.0'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ module Rip::Parser
2
+ class Error < StandardError
3
+ attr_reader :code
4
+
5
+ def initialize(message)
6
+ super
7
+ @code = 10
8
+ end
9
+ end
10
+
11
+ class SyntaxError < Error
12
+ attr_reader :location
13
+ attr_reader :cause
14
+
15
+ def initialize(message, location, cause)
16
+ super(message)
17
+
18
+ @location = location
19
+ @cause = cause
20
+ @code = 11
21
+ end
22
+ end
23
+
24
+ class NormalizeError < Error
25
+ attr_reader :origin
26
+ attr_reader :tree
27
+
28
+ def initialize(message, origin, tree = nil)
29
+ super(message)
30
+
31
+ @origin = origin
32
+ @tree = tree
33
+ @code = 12
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ require 'parslet'
2
+
3
+ require_relative './rules'
4
+
5
+ module Rip::Parser
6
+ class Grammar
7
+ include Rip::Parser::Rules::Module
8
+
9
+ def self.parse(origin, source_code)
10
+ begin
11
+ raw_tree = new.module.parse(source_code)
12
+ Rip::Parser::Utilities::Normalizer.apply(origin, raw_tree)
13
+ rescue Parslet::ParseFailed => e
14
+ match = /\A.+ at line (\d+) char (\d+)\.\z/.match(e.message)
15
+ line, column = match ? match.values_at(1, 2).map(&:to_i) : [ 0, 0 ]
16
+ location = Rip::Parser::Location.new(origin, e.cause.pos.charpos, line, column)
17
+ raise Rip::Parser::SyntaxError.new(e.message, location, e.cause)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ require_relative './utilities/normalizer'
@@ -0,0 +1,84 @@
1
+ module Rip::Parser
2
+ class Keyword
3
+ attr_reader :name
4
+ attr_reader :source_text
5
+
6
+ def initialize(name, source_text = name)
7
+ @name = name.to_sym
8
+ @source_text = source_text.to_s
9
+ end
10
+
11
+ def ==(other)
12
+ name == other.name
13
+ end
14
+
15
+ def to_debug
16
+ name
17
+ end
18
+
19
+ def self.[](name)
20
+ Keywords.all.detect do |keyword|
21
+ keyword.name == name
22
+ end.tap do |keyword|
23
+ raise "Unknown keyword: `#{name}`" if keyword.nil?
24
+ end
25
+ end
26
+ end
27
+
28
+ module Keywords
29
+ def self.all
30
+ [
31
+ conditional,
32
+ dependency,
33
+ exceptional,
34
+ object,
35
+ pseudo,
36
+ query,
37
+ transfer
38
+ ].inject(&:+)
39
+ end
40
+
41
+ def self.conditional
42
+ make_keywords(:if, :switch, :case, :else)
43
+ end
44
+
45
+ def self.dependency
46
+ make_keywords(:import)
47
+ end
48
+
49
+ def self.exceptional
50
+ make_keywords(:try, :catch, :finally)
51
+ end
52
+
53
+ def self.object
54
+ [
55
+ *make_keywords(:class, :enum, :interface),
56
+ Keyword.new(:swerve_rocket, '~>'),
57
+ Keyword.new(:dash_rocket, '->'),
58
+ Keyword.new(:fat_rocket, '=>')
59
+ ]
60
+ end
61
+
62
+ def self.pseudo
63
+ [
64
+ Keyword.new(:class_self, 'self'),
65
+ Keyword.new(:class_prototype, '@'),
66
+ Keyword.new(:lambda_receiver, '@')
67
+ ]
68
+ end
69
+
70
+ def self.query
71
+ make_keywords(:from, :as, :join, :union, :on, :where, :order, :select, :limit, :take)
72
+ end
73
+
74
+ def self.transfer
75
+ make_keywords(:exit, :return, :throw)
76
+ end
77
+
78
+ protected
79
+
80
+ def self.make_keywords(*names)
81
+ names.map { |name| Keyword.new(name) }
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,47 @@
1
+ module Rip::Parser
2
+ class Location
3
+ attr_reader :origin # label where source code is coming from
4
+ attr_reader :offset # zero-based offset from begining of file
5
+ attr_reader :line # one-based line number
6
+ attr_reader :column # one-based character on line
7
+ attr_reader :length # how many characters are covered
8
+
9
+ def initialize(origin, offset, line, column, length = 0)
10
+ @origin = origin
11
+ @offset = offset
12
+ @line = line
13
+ @column = column
14
+ @length = length
15
+ end
16
+
17
+ def ==(other)
18
+ (origin == other.origin) &&
19
+ (offset == other.offset)
20
+ end
21
+
22
+ def add_character(count = 1)
23
+ self.class.new(origin, offset + count, line, column + count, length)
24
+ end
25
+
26
+ def add_line(count = 1)
27
+ self.class.new(origin, offset + count, line + count, 1, length)
28
+ end
29
+
30
+ def inspect
31
+ "#<#{self.class.name} #{self}>"
32
+ end
33
+
34
+ def to_s
35
+ "#{origin}:#{to_debug}"
36
+ end
37
+
38
+ def to_debug
39
+ offset_length = length.zero? ? offset : (offset..(offset + length - 1))
40
+ "#{line}:#{column}(#{offset_length})"
41
+ end
42
+
43
+ def self.from_slice(origin, slice, length = slice.length)
44
+ new(origin, slice.offset, *slice.line_and_column, length)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,115 @@
1
+ module Rip::Parser
2
+ class Node
3
+ include Enumerable
4
+
5
+ attr_reader :location
6
+ attr_reader :type
7
+ attr_reader :extra
8
+
9
+ def initialize(location:, type:, **extra)
10
+ @location = location
11
+ @type = type
12
+ @extra = extra.inject({}) do |memo, (key, value)|
13
+ memo.merge(key => self.class.try_convert(value))
14
+ end
15
+ end
16
+
17
+ def ==(other)
18
+ to_h == other.to_h
19
+ end
20
+
21
+ def [](key)
22
+ case key.to_sym
23
+ when :location then location
24
+ when :type then type
25
+ else extra[key.to_sym]
26
+ end
27
+ end
28
+
29
+ def each(&block)
30
+ to_h.each(&block)
31
+ end
32
+
33
+ def key?(key)
34
+ extra.key?(key.to_sym)
35
+ end
36
+
37
+ def keys
38
+ extra.keys
39
+ end
40
+
41
+ def length
42
+ location.length
43
+ end
44
+
45
+ def merge(other)
46
+ self.class.new(extra.merge(other.to_h).merge(location: location, type: other[:type] || type))
47
+ end
48
+
49
+ def s_expression
50
+ _extra = extra.map do |key, value|
51
+ [ key, self.class.try_convert_s_expression(value) ]
52
+ end.to_h
53
+
54
+ { type: type }.merge(_extra)
55
+ end
56
+
57
+ def to_h
58
+ _extra = extra.map do |key, value|
59
+ [ key, self.class.try_convert_to_h(value) ]
60
+ end.to_h
61
+
62
+ { location: location, type: type }.merge(_extra)
63
+ end
64
+
65
+ private
66
+
67
+ def method_missing(missing_method, *args, &block)
68
+ case
69
+ when key?(missing_method)
70
+ extra[missing_method]
71
+ when missing_method.to_s.end_with?('?')
72
+ missing_method.to_s.sub(/\?\z/, '').to_sym == type
73
+ else
74
+ super
75
+ end
76
+ end
77
+
78
+ def respond_to_missing?(name, include_all)
79
+ key?(name) || name.to_s.end_with?('?')
80
+ end
81
+
82
+ def self.try_convert(value)
83
+ case value
84
+ when Array
85
+ value.map(&method(:try_convert))
86
+ when Hash
87
+ new(value)
88
+ else
89
+ value
90
+ end
91
+ end
92
+
93
+ def self.try_convert_to_h(value)
94
+ case value
95
+ when Array
96
+ value.map(&method(:try_convert_to_h))
97
+ when self
98
+ value.to_h
99
+ else
100
+ value
101
+ end
102
+ end
103
+
104
+ def self.try_convert_s_expression(value)
105
+ case value
106
+ when Array
107
+ value.map(&method(:try_convert_s_expression))
108
+ when self
109
+ value.s_expression
110
+ else
111
+ value
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,23 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './expression'
5
+ require_relative './property'
6
+ require_relative './reference'
7
+
8
+ module Rip::Parser::Rules
9
+ module Assignment
10
+ include ::Parslet
11
+
12
+ include Rip::Parser::Rules::Common
13
+ include Rip::Parser::Rules::Expression
14
+ include Rip::Parser::Rules::Property
15
+ include Rip::Parser::Rules::Reference
16
+
17
+ rule(:reference_assignment) { reference.as(:lhs) >> assignment_rhs }
18
+
19
+ rule(:property_assignment) { (reference.as(:object) >> property).as(:lhs) >> assignment_rhs }
20
+
21
+ rule(:assignment_rhs) { spaces >> equals.as(:location) >> whitespaces >> expression.as(:rhs) }
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './lambda'
5
+ require_relative './keyword'
6
+
7
+ module Rip::Parser::Rules
8
+ module BinaryCondition
9
+ include ::Parslet
10
+
11
+ include Rip::Parser::Rules::Common
12
+ include Rip::Parser::Rules::Lambda
13
+ include Rip::Parser::Rules::Keyword
14
+
15
+ rule(:binary_condition) do
16
+ keyword(:if) >> whitespaces? >>
17
+ parenthesis_open >> whitespaces? >>
18
+ expression.as(:condition) >>
19
+ parenthesis_close >> whitespaces? >>
20
+ block_body(:consequence) >> whitespaces? >>
21
+ keyword(:else) >> whitespaces? >> block_body(:alternative)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './number'
5
+ require_relative './reference'
6
+
7
+ module Rip::Parser::Rules
8
+ module Character
9
+ include ::Parslet
10
+
11
+ include Rip::Parser::Rules::Common
12
+ include Rip::Parser::Rules::Number
13
+ include Rip::Parser::Rules::Reference
14
+
15
+ SPECIAL_ESCAPES = {
16
+ quote_single: "'",
17
+ quote_double: '"',
18
+ backslash: '\\',
19
+ bell: 'a',
20
+ backspace: 'b',
21
+ form_feed: 'f',
22
+ new_line: 'n',
23
+ carriage_return: 'r',
24
+ tab_horizontal: 't',
25
+ tab_vertical: 'v'
26
+ }
27
+
28
+ rule(:character) { backtick.as(:location) >> (escape_sequence | character_legal.as(:character)) }
29
+
30
+ rule(:character_legal) { digit | word_legal }
31
+
32
+ rule(:backtick) { str('`') }
33
+
34
+ rule(:escape_sequence) { slash_back.as(:escape_location) >> (escape_sequence_unicode | escape_sequence_special | escape_sequence_any) }
35
+
36
+ rule(:escape_sequence_unicode) { str('u') >> match['0-9a-f'].repeat(4, 4).as(:escape_unicode) }
37
+ rule(:escape_sequence_special) { SPECIAL_ESCAPES.values.map(&method(:str)).inject(&:|).as(:escape_special) }
38
+ rule(:escape_sequence_any) { match['\S'].as(:escape_any) }
39
+ end
40
+ end
@@ -0,0 +1,60 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './keyword'
5
+ require_relative './lambda'
6
+ require_relative './property'
7
+ require_relative './reference'
8
+
9
+ module Rip::Parser::Rules
10
+ module Class
11
+ include ::Parslet
12
+
13
+ include Rip::Parser::Rules::Common
14
+ include Rip::Parser::Rules::Keyword
15
+ include Rip::Parser::Rules::Lambda
16
+ include Rip::Parser::Rules::Property
17
+ include Rip::Parser::Rules::Reference
18
+
19
+ rule(:class_block) do
20
+ keyword(:class) >> spaces? >> class_ancestors.maybe >> whitespaces? >> brace_open >>
21
+ class_body.maybe.as(:body) >>
22
+ whitespaces? >> brace_close
23
+ end
24
+
25
+ rule(:class_ancestors) do
26
+ parenthesis_open >> whitespaces? >>
27
+ csv(reference).as(:ancestors) >>
28
+ whitespaces? >> parenthesis_close
29
+ end
30
+
31
+ rule(:class_body) do
32
+ whitespaces? >> class_property_assignment >> spaces? >> (
33
+ (semicolon | line_break) >> whitespaces? >> class_body
34
+ ).repeat(0) >> whitespaces?
35
+ end
36
+
37
+ rule(:class_property_assignment) do
38
+ class_property.as(:property) >> spaces >>
39
+ equals.as(:location) >> whitespaces >>
40
+ property_value.as(:property_value)
41
+ end
42
+
43
+ rule(:class_property) do
44
+ keyword(:class_prototype) >> property |
45
+ keyword(:class_self) >> property |
46
+ word.as(:property_name)
47
+ end
48
+
49
+ rule(:property_value) do
50
+ import |
51
+ class_block |
52
+ lambda_block |
53
+ overload_block |
54
+ property_block |
55
+ expression
56
+ end
57
+
58
+ rule(:property_block) { keyword(:swerve_rocket) >> whitespaces? >> block_body }
59
+ end
60
+ end
@@ -0,0 +1,47 @@
1
+ require 'parslet'
2
+
3
+ module Rip::Parser::Rules
4
+ module Common
5
+ include ::Parslet
6
+
7
+ rule(:whitespace) { space | line_break | comment }
8
+ rule(:whitespaces) { whitespace.repeat(1) }
9
+ rule(:whitespaces?) { whitespaces.maybe }
10
+
11
+ rule(:space) { str(' ') | str("\t") }
12
+ rule(:spaces) { space.repeat(1) }
13
+ rule(:spaces?) { spaces.maybe }
14
+
15
+ rule(:line_break) { str("\r\n") | str("\n") | str("\r") }
16
+ rule(:line_breaks) { line_break.repeat(1) }
17
+ rule(:line_breaks?) { line_breaks.maybe }
18
+
19
+ rule(:comment) { pound >> (line_break.absent? >> any).repeat >> (line_break | eof) }
20
+
21
+ rule(:eof) { any.absent? }
22
+
23
+ rule(:dot) { str('.') }
24
+ rule(:comma) { str(',') }
25
+ rule(:semicolon) { str(';') }
26
+ rule(:colon) { str(':') }
27
+ rule(:pound) { str('#') }
28
+ rule(:dash) { str('-') }
29
+ rule(:underscore) { str('_') }
30
+ rule(:equals) { str('=') }
31
+
32
+ rule(:slash_back) { str('\\') }
33
+ rule(:slash_forward) { str('/') }
34
+
35
+ rule(:angled_open) { str('<') }
36
+ rule(:angled_close) { str('>') }
37
+
38
+ rule(:brace_open) { str('{') }
39
+ rule(:brace_close) { str('}') }
40
+
41
+ rule(:bracket_open) { str('[') }
42
+ rule(:bracket_close) { str(']') }
43
+
44
+ rule(:parenthesis_open) { str('(') }
45
+ rule(:parenthesis_close) { str(')') }
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+ require 'parslet'
2
+
3
+ require_relative './common'
4
+ require_relative './number'
5
+
6
+ module Rip::Parser::Rules
7
+ module DateTime
8
+ include ::Parslet
9
+
10
+ include Rip::Parser::Rules::Common
11
+ include Rip::Parser::Rules::Number
12
+
13
+ rule(:date_time) { date.as(:date) >> str('T') >> time.as(:time) }
14
+
15
+ rule(:date) do
16
+ digit.repeat(4, 4).as(:year) >> dash >>
17
+ digit.repeat(2, 2).as(:month) >> dash >>
18
+ digit.repeat(2, 2).as(:day)
19
+ end
20
+
21
+ rule(:time) do
22
+ digit.repeat(2, 2).as(:hour) >> colon >>
23
+ digit.repeat(2, 2).as(:minute) >> colon >>
24
+ digit.repeat(2, 2).as(:second) >>
25
+ (dot >> digits.as(:sub_second)).maybe >>
26
+ (
27
+ sign >> digit.repeat(2, 2).as(:hour) >> digit.repeat(2, 2).as(:minute)
28
+ ).as(:offset).maybe
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,122 @@
1
+ require 'parslet'
2
+
3
+ require_relative './binary_condition'
4
+ require_relative './class'
5
+ require_relative './character'
6
+ require_relative './common'
7
+ require_relative './date_time'
8
+ require_relative './import'
9
+ require_relative './invocation'
10
+ require_relative './invocation_index'
11
+ require_relative './keyword'
12
+ require_relative './lambda'
13
+ require_relative './list'
14
+ require_relative './map'
15
+ require_relative './number'
16
+ require_relative './pair'
17
+ require_relative './property'
18
+ require_relative './range'
19
+ require_relative './reference'
20
+ require_relative './string'
21
+ require_relative './unit'
22
+
23
+ module Rip::Parser::Rules
24
+ module Expression
25
+ include ::Parslet
26
+
27
+ include Rip::Parser::Rules::BinaryCondition
28
+
29
+ include Rip::Parser::Rules::Common
30
+
31
+ include Rip::Parser::Rules::Class
32
+
33
+ include Rip::Parser::Rules::DateTime
34
+
35
+ include Rip::Parser::Rules::Number
36
+
37
+ include Rip::Parser::Rules::Character
38
+ include Rip::Parser::Rules::String
39
+
40
+ include Rip::Parser::Rules::Lambda
41
+
42
+ include Rip::Parser::Rules::List
43
+
44
+ include Rip::Parser::Rules::Keyword
45
+
46
+ include Rip::Parser::Rules::Import
47
+
48
+ include Rip::Parser::Rules::Invocation
49
+ include Rip::Parser::Rules::InvocationIndex
50
+
51
+ include Rip::Parser::Rules::Map
52
+
53
+ include Rip::Parser::Rules::Pair
54
+
55
+ include Rip::Parser::Rules::Property
56
+
57
+ include Rip::Parser::Rules::Range
58
+
59
+ include Rip::Parser::Rules::Reference
60
+
61
+ include Rip::Parser::Rules::Unit
62
+
63
+ rule(:expression) { expression_chain }
64
+
65
+ rule(:expression_chain) do
66
+ (
67
+ (
68
+ expression_base |
69
+ (parenthesis_open >> whitespaces? >> expression_chain >> whitespaces? >> parenthesis_close)
70
+ ) >> expression_link.repeat
71
+ ).as(:expression_chain)
72
+ end
73
+
74
+ rule(:expression_base) do
75
+ import |
76
+
77
+ class_block |
78
+
79
+ lambda_block |
80
+ overload_block |
81
+
82
+ # enum_block |
83
+
84
+ binary_condition |
85
+
86
+ # switch_block |
87
+
88
+ # exception_block_sequence |
89
+
90
+ date_time |
91
+ date |
92
+ time |
93
+
94
+ unit |
95
+
96
+ # version | # maybe
97
+
98
+ number |
99
+
100
+ character |
101
+
102
+ string |
103
+ regular_expression |
104
+
105
+ # markup_fragment |
106
+
107
+ list |
108
+
109
+ map |
110
+
111
+ reference
112
+ end
113
+
114
+ rule(:expression_link) do
115
+ property |
116
+ pair_value |
117
+ range_end |
118
+ invocation |
119
+ invocation_index
120
+ end
121
+ end
122
+ end