Commit cee3be29 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Add a lexeme for a string pipeline expression

parent 9954928c
...@@ -2,32 +2,34 @@ module Gitlab ...@@ -2,32 +2,34 @@ module Gitlab
module Ci module Ci
module Pipeline module Pipeline
module Expression module Expression
LEXEMES = [ class Lexer
Expression::Variable LEXEMES = [
] Expression::Variable,
Expression::String
]
MAX_CYCLES = 5 MAX_CYCLES = 5
SyntaxError = Class.new(StandardError)
class Lexer
def initialize(statement) def initialize(statement)
@scanner = StringScanner.new(statement) @scanner = StringScanner.new(statement)
@tokens = [] @tokens = []
end end
def tokenize def tokenize
@tokens.tap do MAX_CYCLES.times do
MAX_CYCLES.times do LEXEMES.each do |lexeme|
LEXEMES.each do |lexeme| @scanner.scan(/\s+/) # ignore whitespace
@scanner.scan(/\s+/) # ignore whitespace
lexeme.scan(@scanner).tap do |token|
@tokens.push(token) if token.present?
end
return @tokens if @scanner.eos? lexeme.scan(@scanner).tap do |token|
@tokens.push(token) if token.present?
end end
return @tokens if @scanner.eos?
end end
end end
raise Lexer::SyntaxError unless @scanner.eos?
end end
end end
end end
......
...@@ -3,7 +3,7 @@ module Gitlab ...@@ -3,7 +3,7 @@ module Gitlab
module Pipeline module Pipeline
module Expression module Expression
class String < Expression::Lexeme class String < Expression::Lexeme
PATTERN = /("|')(?<value>.+)('|")/.freeze PATTERN = /"(?<string>.+?)"/.freeze
def initialize(value) def initialize(value)
@value = value @value = value
......
...@@ -3,6 +3,8 @@ module Gitlab ...@@ -3,6 +3,8 @@ module Gitlab
module Pipeline module Pipeline
module Expression module Expression
class Token class Token
attr_reader :value, :type
def initialize(value, type) def initialize(value, type)
@value = value @value = value
@type = type @type = type
......
...@@ -26,5 +26,21 @@ describe Gitlab::Ci::Pipeline::Expression::Lexer do ...@@ -26,5 +26,21 @@ describe Gitlab::Ci::Pipeline::Expression::Lexer do
expect(tokens.size).to eq 2 expect(tokens.size).to eq 2
expect(tokens).to all(be_an_instance_of(token_class)) expect(tokens).to all(be_an_instance_of(token_class))
end end
it 'tokenizes multiple values with different tokens' do
tokens = described_class.new('$VARIABLE "text" "value"').tokenize
expect(tokens.size).to eq 3
expect(tokens.first.value).to eq '$VARIABLE'
expect(tokens.second.value).to eq '"text"'
expect(tokens.third.value).to eq '"value"'
end
it 'limits statement to 5 tokens' do
lexer = described_class.new("$V1 $V2 $V3 $V4 $V5 $V6")
expect { lexer.tokenize }
.to raise_error described_class::SyntaxError
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment