Enforce names= definition before parse()
This commit is contained in:
parent
a10d8db8a9
commit
f08fb17b41
5 changed files with 101 additions and 0 deletions
|
@ -181,8 +181,22 @@ module Namarara
|
||||||
# 8< ---- 8< ---- ...
|
# 8< ---- 8< ---- ...
|
||||||
|
|
||||||
class Parser < Rly::Yacc
|
class Parser < Rly::Yacc
|
||||||
|
class MissingNamesError < RuntimeError; end
|
||||||
attr_writer :names
|
attr_writer :names
|
||||||
|
|
||||||
|
# Initialize names hash
|
||||||
|
def initialize(*args)
|
||||||
|
@names = nil
|
||||||
|
super(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Make sure names are filled in
|
||||||
|
def parse(str)
|
||||||
|
raise MissingNamesError if @names.nil?
|
||||||
|
|
||||||
|
super(str)
|
||||||
|
end
|
||||||
|
|
||||||
# Check if grammar is valid
|
# Check if grammar is valid
|
||||||
def check_grammar(line, tokens)
|
def check_grammar(line, tokens)
|
||||||
grammar = tokens.to_s.split(/=|AND|OR/)
|
grammar = tokens.to_s.split(/=|AND|OR/)
|
||||||
|
|
35
spec/example-multi-expr.rb
Normal file
35
spec/example-multi-expr.rb
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
require 'namarara'
|
||||||
|
|
||||||
|
# Initialize Namarara
|
||||||
|
namarara = Namarara::Parser.new(Namarara::Lexer.new)
|
||||||
|
|
||||||
|
# A set of rules i want to check
|
||||||
|
rules = {
|
||||||
|
vulnerable_person: 'is_adult AND is_subordinate',
|
||||||
|
has_constraints: 'is_adult AND has_children',
|
||||||
|
is_child: 'NOT is_adult'
|
||||||
|
# ...
|
||||||
|
}
|
||||||
|
|
||||||
|
# A set of values i want to inject (values must be expressed as strings)
|
||||||
|
namarara.names = {
|
||||||
|
"is_adult" => 'false',
|
||||||
|
"is_subordinate" => 'true',
|
||||||
|
"has_children" => 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
rules.map do |rule|
|
||||||
|
namarara_bet = namarara.parse(rule.expr)
|
||||||
|
result = namarara_bet.compute
|
||||||
|
if result then
|
||||||
|
warnings << "Rule #{rule} is true"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not warnings.empty?
|
||||||
|
puts "Warning: you are collectif sensitive personnal data !"
|
||||||
|
puts warnings.join("\n")
|
||||||
|
else
|
||||||
|
puts "Perfect! Nothing to say ;-)"
|
||||||
|
end
|
21
spec/example-single-expr.rb
Normal file
21
spec/example-single-expr.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
require 'namarara'
|
||||||
|
|
||||||
|
# Initialize Namarara
|
||||||
|
namarara = Namarara::Parser.new(Namarara::Lexer.new)
|
||||||
|
|
||||||
|
# Build the binary expression tree (aka BET)
|
||||||
|
exp_tree = namarara.parse('this AND (that OR other) AND something_else')
|
||||||
|
puts p
|
||||||
|
|
||||||
|
# Prepare variables
|
||||||
|
exp_tree.names = {
|
||||||
|
this: 'true',
|
||||||
|
that: 'false',
|
||||||
|
other: 'false',
|
||||||
|
something_else: 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compute tree with variables
|
||||||
|
result = exp_tree.compute
|
||||||
|
puts "#{result} == "
|
|
@ -10,12 +10,14 @@ describe Namarara::Parser do
|
||||||
|
|
||||||
it 'has to do not before or' do
|
it 'has to do not before or' do
|
||||||
line = 'NOT true OR NOT true'
|
line = 'NOT true OR NOT true'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal('( NOT ( bool:true ) ) OR ( NOT ( bool:true ) )', token.to_s)
|
assert_equal('( NOT ( bool:true ) ) OR ( NOT ( bool:true ) )', token.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has to do not before and' do
|
it 'has to do not before and' do
|
||||||
line = 'NOT false AND NOT false'
|
line = 'NOT false AND NOT false'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(
|
assert_equal(
|
||||||
'( NOT ( bool:false ) ) AND ( NOT ( bool:false ) )',
|
'( NOT ( bool:false ) ) AND ( NOT ( bool:false ) )',
|
||||||
|
@ -25,6 +27,7 @@ describe Namarara::Parser do
|
||||||
|
|
||||||
it 'has to do and before or' do
|
it 'has to do and before or' do
|
||||||
line = 'false OR true AND false'
|
line = 'false OR true AND false'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(
|
assert_equal(
|
||||||
'( bool:false ) OR ( ( bool:true ) AND ( bool:false ) )',
|
'( bool:false ) OR ( ( bool:true ) AND ( bool:false ) )',
|
||||||
|
@ -34,6 +37,7 @@ describe Namarara::Parser do
|
||||||
|
|
||||||
it 'has to do and before or operators' do
|
it 'has to do and before or operators' do
|
||||||
line = 'false OR false AND true OR true'
|
line = 'false OR false AND true OR true'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(
|
assert_equal(
|
||||||
'( ( bool:false ) OR ( ( bool:false ) '\
|
'( ( bool:false ) OR ( ( bool:false ) '\
|
||||||
|
|
|
@ -17,24 +17,28 @@ describe Namarara::Parser do
|
||||||
|
|
||||||
it 'has to find true boolean and compute it to expr' do
|
it 'has to find true boolean and compute it to expr' do
|
||||||
line = 'true'
|
line = 'true'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has to find false boolean and compute it to expr' do
|
it 'has to find false boolean and compute it to expr' do
|
||||||
line = 'false'
|
line = 'false'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(false, token.compute)
|
assert_equal(false, token.compute)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has to find parenthesis expr and compute it to expr' do
|
it 'has to find parenthesis expr and compute it to expr' do
|
||||||
line = '( true )'
|
line = '( true )'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has to apply not on expr' do
|
it 'has to apply not on expr' do
|
||||||
line = 'NOT true'
|
line = 'NOT true'
|
||||||
|
parser.names = {}
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(false, token.compute)
|
assert_equal(false, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -170,4 +174,27 @@ describe Namarara::Parser do
|
||||||
token = parser.parse(line)
|
token = parser.parse(line)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'cannot parse before setting names' do
|
||||||
|
line = 'multi_face_god AND character'
|
||||||
|
|
||||||
|
assert_raises Namarara::Parser::MissingNamesError do
|
||||||
|
token = parser.parse(line)
|
||||||
|
parser.names = {
|
||||||
|
'multi_face_god' => 3,
|
||||||
|
'character' => 1
|
||||||
|
}
|
||||||
|
assert_equal(true, token.compute)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can set names before parsing' do
|
||||||
|
line = 'a_girl_has_no_name AND multi_face_god'
|
||||||
|
parser.names = {
|
||||||
|
'a_girl_has_no_name' => 3,
|
||||||
|
'multi_face_god' => 1
|
||||||
|
}
|
||||||
|
token = parser.parse(line)
|
||||||
|
assert_equal(true, token.compute)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue