summaryrefslogtreecommitdiff
path: root/lib/hcl2.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hcl2.rb')
-rw-r--r--lib/hcl2.rb102
1 files changed, 102 insertions, 0 deletions
diff --git a/lib/hcl2.rb b/lib/hcl2.rb
index fa7b2e7..e6f2fb8 100644
--- a/lib/hcl2.rb
+++ b/lib/hcl2.rb
@@ -1,7 +1,109 @@
# frozen_string_literal: true
+require "parslet"
require_relative "hcl2/version"
module Hcl2
class Error < StandardError; end
+
+ class Parser < ::Parslet::Parser
+ rule(:alpha) { match['a-zA-Z'] }
+ rule(:assign) { str('=') }
+ rule(:colon) { str(':') }
+ rule(:comma) { str(',') }
+ rule(:comment) { (str('#') | str('//')) >> ((str("\n") >> str("\r").maybe).absent? >> any).repeat >> eol }
+ rule(:crlf) { match('[\r\n]') }
+ rule(:digit) { match('\d') }
+ rule(:dot) { str('.') }
+ rule(:eol) { whitespace? >> crlf.repeat }
+ rule(:greater_than_or_equal_to) { str('>=') }
+ rule(:hyphen) { str('-') }
+ rule(:lbracket) { str('[') }
+ rule(:lcurly) { str('{') }
+ rule(:major) { number }
+ rule(:major_minor) { (number >> dot >> number) }
+ rule(:major_minor_patch) { number >> dot >> number >> dot >> number }
+ rule(:multiline_comment) { str('/*') >> (str('*/').absent? >> any).repeat >> str('*/') }
+ rule(:number) { digit.repeat }
+ rule(:plus) { str('+') }
+ rule(:pre_release) { hyphen >> (alpha | digit).repeat }
+ rule(:pre_release?) { pre_release.maybe }
+ rule(:quote) { str('"') }
+ rule(:rbracket) { str(']') }
+ rule(:rcurly) { str('}') }
+ rule(:slash) { str('/') }
+ rule(:space) { match('\s') }
+ rule(:tilda_wacka) { str('~>') }
+ rule(:version) { number >> dot >> number >> dot >> number >> pre_release? }
+ rule(:whitespace) { (multiline_comment | comment | space).repeat }
+ rule(:whitespace?) { whitespace.maybe }
+
+ rule(:pessimistic_version_constraint) do
+ tilda_wacka >> whitespace >> (
+ major_minor_patch |
+ major_minor |
+ major
+ )
+ end
+
+ rule(:greater_than_or_equal_to_version) do
+ greater_than_or_equal_to >> whitespace >> (
+ major_minor_patch |
+ major_minor |
+ major
+ )
+ end
+
+ rule(:version_constraint) do
+ pessimistic_version_constraint | greater_than_or_equal_to_version
+ end
+
+ rule :version_assignment do
+ str('version') >> whitespace >> assign >> whitespace >> quote >> version.as(:version) >> quote
+ end
+
+ rule :constraint_assignment do
+ str('constraints') >> whitespace >> assign >> whitespace >> quote >> version_constraint.as(:constraints) >> quote
+ end
+
+ rule :string do
+ quote >> (
+ digit | dot | alpha | str('~> ') | slash | colon | assign | plus
+ ).repeat(1).as(:value) >> quote
+ end
+
+ rule :array_item do
+ whitespace? >> string >> comma.maybe >> eol
+ end
+
+ rule :array do
+ lbracket >> eol >> array_item.repeat >> whitespace >> rbracket
+ end
+
+ rule :argument_value do
+ (array.as(:values) | string) >> eol
+ end
+
+ rule :argument do
+ whitespace >> alpha.repeat(1).as(:name) >> whitespace >> assign >> whitespace >> argument_value
+ end
+
+ rule :block_body do
+ lcurly >> crlf >> argument.repeat.as(:arguments) >> rcurly
+ end
+
+ rule :identifier do
+ whitespace >> quote >> (alpha | dot | slash).repeat(1).as(:name) >> quote >> whitespace
+ end
+
+ rule :block do
+ alpha.repeat(1).as(:type) >> identifier >> block_body
+ end
+
+ rule :blocks do
+ whitespace? >> (block >> eol.maybe).repeat(1).as(:blocks)
+ end
+
+ root(:blocks)
+ end
end