diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2018-02-21 13:38:37 +0100 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2018-02-21 13:38:37 +0100 |
commit | 2c4aa50463ed411b14003f9d929c1e03518953bf (patch) | |
tree | df950739c517127280aa1b301bb884470fe511de /lib | |
parent | 91a42a1a8f0d4bfc63e41b2f7b29a2b0fee1a60c (diff) | |
download | gitlab-ce-2c4aa50463ed411b14003f9d929c1e03518953bf.tar.gz |
Implement pipeline expressions parser
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/ci/pipeline/expression/lexeme.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/expression/lexer.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/expression/statement.rb | 33 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/expression/string.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/expression/token.rb | 5 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/expression/variable.rb | 8 |
6 files changed, 49 insertions, 5 deletions
diff --git a/lib/gitlab/ci/pipeline/expression/lexeme.rb b/lib/gitlab/ci/pipeline/expression/lexeme.rb index bbf3fec7407..91ba333d8dd 100644 --- a/lib/gitlab/ci/pipeline/expression/lexeme.rb +++ b/lib/gitlab/ci/pipeline/expression/lexeme.rb @@ -7,6 +7,10 @@ module Gitlab raise NotImplementedError end + def self.build(token) + raise NotImplementedError + end + def self.scan(scanner) if scanner.scan(self::PATTERN) Expression::Token.new(scanner.matched, self) diff --git a/lib/gitlab/ci/pipeline/expression/lexer.rb b/lib/gitlab/ci/pipeline/expression/lexer.rb index 8432b36b066..ee202ebce69 100644 --- a/lib/gitlab/ci/pipeline/expression/lexer.rb +++ b/lib/gitlab/ci/pipeline/expression/lexer.rb @@ -5,7 +5,8 @@ module Gitlab class Lexer LEXEMES = [ Expression::Variable, - Expression::String + Expression::String, + Expression::Equals ] MAX_CYCLES = 5 diff --git a/lib/gitlab/ci/pipeline/expression/statement.rb b/lib/gitlab/ci/pipeline/expression/statement.rb index 91d91195f5a..417b3f806b1 100644 --- a/lib/gitlab/ci/pipeline/expression/statement.rb +++ b/lib/gitlab/ci/pipeline/expression/statement.rb @@ -3,6 +3,8 @@ module Gitlab module Pipeline module Expression class Statement + ParserError = Class.new(StandardError) + GRAMMAR = [ %w[variable equals string], %w[variable equals variable], @@ -12,14 +14,41 @@ module Gitlab %w[variable] ] - def initialize(pipeline, statement) + def initialize(statement, pipeline) @pipeline = pipeline - @statement = statement + @lexer = Expression::Lexer.new(statement) end def variables end + def tokens + @lexer.tokenize + end + + def lexemes + @lexemes ||= tokens.map(&:to_lexeme) + end + + ## + # Our syntax is very simple, so we don't need yet to implement a + # recurisive parser, we can use the most simple approach to create + # a reverse descent parse tree "by hand". + # + def parse_tree + raise ParserError if lexemes.empty? + + unless GRAMMAR.find { |syntax| syntax == lexemes } + raise ParserError, 'Unknown pipeline expression!' + end + + if lexemes.many? + Expression::Equals.new(tokens.first.build, tokens.last.build) + else + tokens.first.build + end + end + def evaluate end end diff --git a/lib/gitlab/ci/pipeline/expression/string.rb b/lib/gitlab/ci/pipeline/expression/string.rb index e6cc50c56d8..6a59b81467c 100644 --- a/lib/gitlab/ci/pipeline/expression/string.rb +++ b/lib/gitlab/ci/pipeline/expression/string.rb @@ -14,6 +14,7 @@ module Gitlab end def self.build(string) + new(string.match(PATTERN)[:string]) end end end diff --git a/lib/gitlab/ci/pipeline/expression/token.rb b/lib/gitlab/ci/pipeline/expression/token.rb index 03a47a17d40..3b957c83016 100644 --- a/lib/gitlab/ci/pipeline/expression/token.rb +++ b/lib/gitlab/ci/pipeline/expression/token.rb @@ -10,7 +10,12 @@ module Gitlab @type = type end + def build + @type.build(@value) + end + def to_lexeme + type.name.demodulize.downcase end end end diff --git a/lib/gitlab/ci/pipeline/expression/variable.rb b/lib/gitlab/ci/pipeline/expression/variable.rb index ec6c03d336a..d6a7a655220 100644 --- a/lib/gitlab/ci/pipeline/expression/variable.rb +++ b/lib/gitlab/ci/pipeline/expression/variable.rb @@ -5,12 +5,16 @@ module Gitlab class Variable < Expression::Lexeme PATTERN = /\$(?<name>\w+)/.freeze - def initialize(value) - @value = value + def initialize(name) + @name = name end def evaluate(**variables) end + + def self.build(string) + new(string.match(PATTERN)[:name]) + end end end end |