Add verification for grammar

This commit is contained in:
Roguelearg 2017-09-15 12:52:29 +02:00
parent cc435be659
commit b2d80874e6
11 changed files with 98 additions and 55 deletions

View file

@ -20,7 +20,7 @@ module Mm2ep
vars.each do |var|
tab_vars[var.split('=')[0]] = var.split('=')[1]
end
# Give vars name and value from shell command to parser
parser.names=tab_vars
@ -28,8 +28,11 @@ module Mm2ep
pp token
puts "RAW : #{line}"
puts "EVAL: #{token.to_s}"
exit 1 unless token.errors.empty?
parser.check_grammar line, token
binding.pry
exit 1 unless token.errors.empty? || token.nil?
puts "RESULT: #{token.compute}"
end
end
end

View file

@ -0,0 +1,6 @@
module Mm2ep
module Depend
class InvalidGrammar < Depend::EvalError
end
end
end

View file

@ -1,7 +1,6 @@
module Mm2ep
module Depend
class VarNotDefined < Depend::EvalError
end
end
end

View file

@ -10,3 +10,4 @@ require 'mm2ep_depend/lexer'
require 'mm2ep_depend/parser'
require 'mm2ep_depend/eval_error'
require 'errors/var_not_defined'
require 'errors/invalid_grammar'

View file

@ -12,7 +12,6 @@ module Mm2ep
@message = hash[:message]
@var = hash[:var]
end
end
end
end

View file

@ -1,17 +1,13 @@
module Mm2ep
module Depend
class TreeExpr
def compute
raise NotImplementedError
end
end
class TreeValue
def value
@value
end
attr_reader :value
def to_s
raise NotImplementedError
@ -29,12 +25,11 @@ module Mm2ep
when /false/i then false
else value
end
if @value.nil?
@errors << VarNotDefined.new(
message:"No value for #{@name}",
var: @name
)
end
return unless @value.nil?
@errors << VarNotDefined.new(
message: "No value for #{@name}",
var: @name
)
end
def compute
@ -167,7 +162,6 @@ module Mm2ep
@errors.concat rval.errors
@lval = lval
@rval = rval
end
def compute
@ -181,10 +175,16 @@ module Mm2ep
class Parser < Rly::Yacc
attr_writer :names
attr_reader :errors
# def names(tab)
# @names = tab
# end
def check_grammar(line, tokens)
grammar = tokens.to_s.split(/=|AND|OR/)
expr = line.split(/=|AND|OR/)
return if grammar.size == expr.size
return if grammar.empty?
tokens.errors << InvalidGrammar.new(
message: 'Invalid Grammar'
)
end
precedence :left, :OR_OP
precedence :left, :AND_OP
@ -232,7 +232,6 @@ module Mm2ep
end
rule 'expr : VAR EQ_OP bool_expr' do |ex, v, _eq, n|
# binding.pry
ex.value = EqOp.new(
VarValue.new(v.value.to_s, @names[v.value]),
BoolValue.new(n.value)

View file

@ -0,0 +1 @@
false = "Arya"

View file

@ -0,0 +1 @@
( a_girl_has_no_name = true ) ANDAND ( character = "Arya Stark" ) OR false AND true

View file

@ -0,0 +1,46 @@
require 'spec_helper'
require 'mm2ep_depend'
describe Mm2ep::Depend::Parser do
it 'has to report var which is not defined' do
line = File.read(testfile('simple_eq_expr_boolexpr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names = {}
token = parser.parse(line.chomp)
token.errors
.select do |elem|
elem.is_a? Mm2ep::Depend::VarNotDefined
end.size.must_equal 1
end
it 'has to report vars which are not defined' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names = {}
token = parser.parse(line.chomp)
token.errors
.select do |elem|
elem.is_a? Mm2ep::Depend::VarNotDefined
end.size.must_equal 2
end
it 'has to report invalid_grammar' do
line = File.read(testfile('grammar_partially_invalid.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names = { 'a_girl_has_no_name' => true, 'character' => 'Arya Stark' }
token = parser.parse(line.chomp)
parser.check_grammar line, token
token.errors.select do |elem|
elem.is_a? Mm2ep::Depend::InvalidGrammar
end.size.must_equal 1
end
it 'has to be nil when grammar is completely invalid' do
line = File.read(testfile('grammar_completely_invalid.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names = {}
token = parser.parse(line.chomp)
parser.check_grammar line, token
assert_nil token
end
end

View file

@ -2,7 +2,6 @@ require 'spec_helper'
require 'mm2ep_depend'
describe Mm2ep::Depend::Parser do
it 'has to do not before or' do
line = File.read(testfile('priority_not_or.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
@ -30,5 +29,4 @@ describe Mm2ep::Depend::Parser do
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
end

View file

@ -2,7 +2,6 @@ require 'spec_helper'
require 'mm2ep_depend'
describe Mm2ep::Depend::Parser do
it 'has to apply not on expr' do
line = File.read(testfile('simple_not_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
@ -13,7 +12,7 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate eq with bool expr and return true' do
line = File.read(testfile('simple_eq_expr_boolexpr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true'}
parser.names = { 'truc_bidule' => 'true' }
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
@ -21,7 +20,7 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate eq with bool expr and return false' do
line = File.read(testfile('simple_eq_expr_boolexpr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false'}
parser.names = { 'truc_bidule' => 'false' }
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
@ -29,7 +28,7 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate eq with number and return true' do
line = File.read(testfile('simple_eq_expr_number.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => '10'}
parser.names = { 'truc_bidule' => '10' }
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
@ -37,7 +36,7 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate eq with number and return false' do
line = File.read(testfile('simple_eq_expr_number.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => '11'}
parser.names = { 'truc_bidule' => '11' }
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
@ -45,7 +44,7 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate eq with string and return true' do
line = File.read(testfile('simple_eq_expr_string.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'test'}
parser.names = { 'truc_bidule' => 'test' }
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
@ -53,7 +52,7 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate eq with string and return false' do
line = File.read(testfile('simple_eq_expr_string.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'tes'}
parser.names = { 'truc_bidule' => 'tes' }
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
@ -61,9 +60,8 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate true OR true and return true' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'true'
}
parser.names = { 'truc_bidule' => 'true',
'machin' => 'true' }
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
@ -71,9 +69,8 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate true OR false and return true' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'false'
}
parser.names = { 'truc_bidule' => 'true',
'machin' => 'false' }
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
@ -81,9 +78,8 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate false OR true and return true' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'true'
}
parser.names = { 'truc_bidule' => 'false',
'machin' => 'true' }
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
@ -91,9 +87,8 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate false OR false and return false' do
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'false'
}
parser.names = { 'truc_bidule' => 'false',
'machin' => 'false' }
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
@ -101,9 +96,8 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate true AND true and return true' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'true'
}
parser.names = { 'truc_bidule' => 'true',
'machin' => 'true' }
token = parser.parse(line.chomp)
assert_equal(true, token.compute)
end
@ -111,9 +105,8 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate true AND false and return false' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'true',
'machin' => 'false'
}
parser.names = { 'truc_bidule' => 'true',
'machin' => 'false' }
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
@ -121,9 +114,8 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate false AND true and return false' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'true'
}
parser.names = { 'truc_bidule' => 'false',
'machin' => 'true' }
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
@ -131,11 +123,9 @@ describe Mm2ep::Depend::Parser do
it 'has to evaluate false AND false and return false' do
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
parser.names={'truc_bidule' => 'false',
'machin' => 'false'
}
parser.names = { 'truc_bidule' => 'false',
'machin' => 'false' }
token = parser.parse(line.chomp)
assert_equal(false, token.compute)
end
end