Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2018-03-01 14:16:58 +0300
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2018-03-01 14:16:58 +0300
commit26167c24f6f82e7586a03ecbfa9979a74825585d (patch)
treee9edd69ea6e35f3a316c3a19169518dc972a5285 /lib/gitlab/ci/pipeline/expression/lexer.rb
parent886988c9e1ab6020da9636b935522fac55a19c1e (diff)
Improve pipeline expressions lexer
Diffstat (limited to 'lib/gitlab/ci/pipeline/expression/lexer.rb')
-rw-r--r--lib/gitlab/ci/pipeline/expression/lexer.rb42
1 files changed, 27 insertions, 15 deletions
diff --git a/lib/gitlab/ci/pipeline/expression/lexer.rb b/lib/gitlab/ci/pipeline/expression/lexer.rb
index 067ad5fd312..cabb91d0dd7 100644
--- a/lib/gitlab/ci/pipeline/expression/lexer.rb
+++ b/lib/gitlab/ci/pipeline/expression/lexer.rb
@@ -3,6 +3,8 @@ module Gitlab
module Pipeline
module Expression
class Lexer
+ include ::Gitlab::Utils::StrongMemoize
+
LEXEMES = [
Expression::Lexeme::Variable,
Expression::Lexeme::String,
@@ -10,34 +12,44 @@ module Gitlab
Expression::Lexeme::Equals
].freeze
- MAX_CYCLES = 5
SyntaxError = Class.new(Statement::StatementError)
+ MAX_TOKENS = 100
+
def initialize(statement)
@scanner = StringScanner.new(statement)
- @tokens = []
end
- def tokens
- return @tokens if @tokens.any?
+ def tokens(max: MAX_TOKENS)
+ strong_memoize(:tokens) { tokenize(max) }
+ end
+
+ def lexemes
+ tokens.map(&:to_lexeme)
+ end
+
+ private
- MAX_CYCLES.times do
- LEXEMES.each do |lexeme|
- @scanner.skip(/\s+/) # ignore whitespace
+ def tokenize(max_tokens)
+ tokens = []
- lexeme.scan(@scanner).tap do |token|
- @tokens.push(token) if token.present?
+ max_tokens.times do
+ @scanner.skip(/\s+/) # ignore whitespace
+
+ return tokens if @scanner.eos?
+
+ lexeme = LEXEMES.find do |type|
+ type.scan(@scanner).tap do |token|
+ tokens.push(token) if token.present?
end
+ end
- return @tokens if @scanner.eos?
+ unless lexeme.present?
+ raise Lexer::SyntaxError, 'Unknown lexeme found!'
end
end
- raise Lexer::SyntaxError unless @scanner.eos?
- end
-
- def lexemes
- tokens.map(&:to_lexeme)
+ raise Lexer::SyntaxError, 'Too many tokens!'
end
end
end