Class: LogStashCompilerLSCLGrammar::LogStash::Compiler::LSCL::AST::Condition

Inherits:
Node
  • Object
show all
Includes:
Helpers
Defined in:
lib/logstash/compiler/lscl.rb

Constant Summary

Constants included from Helpers

Helpers::AND_METHOD, Helpers::BOOLEAN_DSL_METHOD_SIGNATURE, Helpers::NAND_METHOD, Helpers::OR_METHOD, Helpers::XOR_METHOD

Instance Method Summary collapse

Methods included from Helpers

#base_id, #base_protocol, #base_source_with_metadata, #base_source_with_metadata=, #compose, #compose_for, #jdsl, jdsl, #line_and_column, #source_meta

Methods inherited from Node

#section_type

Instance Method Details

#exprObject



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/logstash/compiler/lscl.rb', line 296

def expr
  first_element = elements.first
  rest_elements = elements.size > 1 ? elements[1].recursive_select(BooleanOperator, Expression, SelectorElement) : []

  all_elements = [first_element, *rest_elements]


  res = if all_elements.size == 1
    elem = all_elements.first
    if elem.is_a?(Selector)
      jdsl.eTruthy(source_meta, elem.expr)
    elsif elem.is_a?(RegexpExpression)
      elem.expr
    else
      join_conditions(all_elements)
    end
  else
    join_conditions(all_elements)
  end
  res
end

#jconvert(sexpr) ⇒ Object

Converts an sexpr of :and or :or to the java imperative IR



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/logstash/compiler/lscl.rb', line 330

def jconvert(sexpr)
  raise "jconvert cannot handle nils!" if sexpr.nil?

  if sexpr.java_kind_of?(Java::OrgLogstashConfigIrExpression::Expression)
    return sexpr
  end

  op, left, right = sexpr

  left_c = jconvert(left)
  right_c = jconvert(right)

  case op
  when :and
    return jdsl.eAnd(source_meta, left, right);
  when :nand
    return jdsl.eNand(source_meta, left, right);
  when :or
    return jdsl.eOr(source_meta, left, right);
  when :xor
    return jdsl.eXor(source_meta, left, right);
  else
    raise "Unknown op #{jop}"
  end
end

#join_conditions(all_elements) ⇒ Object



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
# File 'lib/logstash/compiler/lscl.rb', line 356

def join_conditions(all_elements)
  # Use Dijkstra's shunting yard algorithm
  out = []
  operators = []

  all_elements.each do |e|
    e_exp = e.expr

    if e.is_a?(BooleanOperator)
      if operators.last && precedence(operators.last) > precedence(e_exp)
        out << operators.pop
      end
      operators << e_exp
    else
      out << e_exp
    end
  end
  operators.reverse.each {|o| out << o}

  stack = []
  expr = []
  out.each do |e|
    if e.is_a?(Symbol)
      rval, lval = stack.pop, stack.pop
      stack << jconvert([e, lval, rval])
    elsif e.nil?
      raise "Nil expr encountered! This should not happen!"
    else
      stack << e
    end
  end

  stack_to_expr(stack)
end

#precedence(op) ⇒ Object



318
319
320
321
322
323
324
325
326
327
# File 'lib/logstash/compiler/lscl.rb', line 318

def precedence(op)
  #  Believe this is right for logstash?
  if op == AND_METHOD
    2
  elsif op == OR_METHOD
    1
  else
    raise ArgumentError, "Unexpected operator #{op}"
  end
end

#stack_to_expr(stack) ⇒ Object



391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/logstash/compiler/lscl.rb', line 391

def stack_to_expr(stack)
  raise "Got an empty stack! This should not happen!" if stack.empty?
  stack = stack.reverse # We need to work the stack in reverse order

  working_stack = []
  while elem = stack.pop
    if elem.is_a?(::Method)
      right, left = working_stack.pop, working_stack.pop
      working_stack << elem.call(source_meta, left, right)
    else
      working_stack << elem
    end
  end

  raise "Invariant violated! Stack size > 1" if working_stack.size > 1

  working_stack.first
end