class InterMine::PathQuery::LogicParser
Attributes
ops[RW]
precedence[RW]
Public Class Methods
new(query)
click to toggle source
# File lib/intermine/query.rb 1489 def initialize(query) 1490 @query = query 1491 end
Public Instance Methods
parse_logic(str)
click to toggle source
# File lib/intermine/query.rb 1493 def parse_logic(str) 1494 tokens = str.upcase.split(/(?:\s+|\b)/).map do |x| 1495 LogicParser.ops.fetch(x, x.split(//)) 1496 end 1497 tokens.flatten! 1498 1499 check_syntax(tokens) 1500 postfix_tokens = infix_to_postfix(tokens) 1501 ast = postfix_to_tree(postfix_tokens) 1502 return ast 1503 end
Private Instance Methods
check_syntax(tokens)
click to toggle source
# File lib/intermine/query.rb 1549 def check_syntax(tokens) 1550 need_op = false 1551 need_bin_op_or_bracket = false 1552 processed = [] 1553 open_brackets = 0 1554 tokens.each do |x| 1555 if !LogicParser.ops.include?(x) 1556 if need_op 1557 raise LogicParseError, "Expected an operator after '#{processed.join(' ')}', but got #{x}" 1558 elsif need_bin_op_or_bracket 1559 raise LogicParseError, "Logic grouping error after '#{processed.join(' ')}', expected an operator or closing bracket, but got #{x}" 1560 end 1561 need_op = true 1562 else 1563 need_op = false 1564 case x 1565 when "(" 1566 if !processed.empty? && !LogicParser.ops.include?(processed.last) 1567 raise LogicParseError, "Logic grouping error after '#{processed.join(' ')}', got #{x}" 1568 elsif need_bin_op_or_bracket 1569 raise LogicParseError, "Logic grouping error after '#{processed.join(' ')}', got #{x}" 1570 end 1571 open_brackets += 1 1572 when ")" 1573 need_bin_op_or_bracket = true 1574 open_brackets -= 1 1575 else 1576 need_bin_op_or_bracket = false 1577 end 1578 end 1579 processed << x 1580 end 1581 if open_brackets < 0 1582 raise LogicParseError, "Unmatched closing bracket in #{tokens.join(' ')}" 1583 elsif open_brackets > 0 1584 raise LogicParseError, "Unmatched opening bracket in #{tokens.join(' ')}" 1585 end 1586 end
infix_to_postfix(tokens)
click to toggle source
# File lib/intermine/query.rb 1507 def infix_to_postfix(tokens) 1508 stack = [] 1509 postfix_tokens = [] 1510 tokens.each do |x| 1511 if !LogicParser.ops.include?(x) 1512 postfix_tokens << x 1513 else 1514 case x 1515 when "(" 1516 stack << x 1517 when ")" 1518 while !stack.empty? 1519 last_op = stack.pop 1520 if last_op == "(" 1521 if !stack.empty? 1522 previous_op = stack.pop 1523 if previous_op != "(" 1524 postfix_tokens << previous_op 1525 break 1526 end 1527 end 1528 else 1529 postfix_tokens << last_op 1530 end 1531 end 1532 else 1533 while !stack.empty? and LogicParser.precedence[stack.last] <= LogicParser.precedence[x] 1534 prev_op = stack.pop 1535 if prev_op != "(" 1536 postfix_tokens << prev_op 1537 end 1538 end 1539 stack << x 1540 end 1541 end 1542 end 1543 while !stack.empty? 1544 postfix_tokens << stack.pop 1545 end 1546 return postfix_tokens 1547 end
postfix_to_tree(tokens)
click to toggle source
# File lib/intermine/query.rb 1588 def postfix_to_tree(tokens) 1589 stack = [] 1590 tokens.each do |x| 1591 if !LogicParser.ops.include?(x) 1592 stack << x 1593 else 1594 right = stack.pop 1595 left = stack.pop 1596 right = (right.is_a?(LogicGroup)) ? right : @query.get_constraint(right) 1597 left = (left.is_a?(LogicGroup)) ? left : @query.get_constraint(left) 1598 stack << LogicGroup.new(left, x, right) 1599 end 1600 end 1601 if stack.size != 1 1602 raise LogicParseError, "Tree does not have a unique root" 1603 end 1604 return stack.pop 1605 end
precedence_of(op)
click to toggle source
# File lib/intermine/query.rb 1607 def precedence_of(op) 1608 return LogicParser.precedence[op] 1609 end