Add verification for grammar
This commit is contained in:
parent
cc435be659
commit
b2d80874e6
11 changed files with 98 additions and 55 deletions
|
@ -28,8 +28,11 @@ module Mm2ep
|
||||||
pp token
|
pp token
|
||||||
puts "RAW : #{line}"
|
puts "RAW : #{line}"
|
||||||
puts "EVAL: #{token.to_s}"
|
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}"
|
puts "RESULT: #{token.compute}"
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
6
lib/errors/invalid_grammar.rb
Normal file
6
lib/errors/invalid_grammar.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module Mm2ep
|
||||||
|
module Depend
|
||||||
|
class InvalidGrammar < Depend::EvalError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,7 +1,6 @@
|
||||||
module Mm2ep
|
module Mm2ep
|
||||||
module Depend
|
module Depend
|
||||||
class VarNotDefined < Depend::EvalError
|
class VarNotDefined < Depend::EvalError
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,3 +10,4 @@ require 'mm2ep_depend/lexer'
|
||||||
require 'mm2ep_depend/parser'
|
require 'mm2ep_depend/parser'
|
||||||
require 'mm2ep_depend/eval_error'
|
require 'mm2ep_depend/eval_error'
|
||||||
require 'errors/var_not_defined'
|
require 'errors/var_not_defined'
|
||||||
|
require 'errors/invalid_grammar'
|
||||||
|
|
|
@ -12,7 +12,6 @@ module Mm2ep
|
||||||
@message = hash[:message]
|
@message = hash[:message]
|
||||||
@var = hash[:var]
|
@var = hash[:var]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
module Mm2ep
|
module Mm2ep
|
||||||
module Depend
|
module Depend
|
||||||
class TreeExpr
|
class TreeExpr
|
||||||
|
|
||||||
def compute
|
def compute
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TreeValue
|
class TreeValue
|
||||||
|
attr_reader :value
|
||||||
def value
|
|
||||||
@value
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -29,13 +25,12 @@ module Mm2ep
|
||||||
when /false/i then false
|
when /false/i then false
|
||||||
else value
|
else value
|
||||||
end
|
end
|
||||||
if @value.nil?
|
return unless @value.nil?
|
||||||
@errors << VarNotDefined.new(
|
@errors << VarNotDefined.new(
|
||||||
message: "No value for #{@name}",
|
message: "No value for #{@name}",
|
||||||
var: @name
|
var: @name
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def compute
|
def compute
|
||||||
@value
|
@value
|
||||||
|
@ -167,7 +162,6 @@ module Mm2ep
|
||||||
@errors.concat rval.errors
|
@errors.concat rval.errors
|
||||||
@lval = lval
|
@lval = lval
|
||||||
@rval = rval
|
@rval = rval
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def compute
|
def compute
|
||||||
|
@ -181,10 +175,16 @@ module Mm2ep
|
||||||
|
|
||||||
class Parser < Rly::Yacc
|
class Parser < Rly::Yacc
|
||||||
attr_writer :names
|
attr_writer :names
|
||||||
attr_reader :errors
|
|
||||||
# def names(tab)
|
def check_grammar(line, tokens)
|
||||||
# @names = tab
|
grammar = tokens.to_s.split(/=|AND|OR/)
|
||||||
# end
|
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, :OR_OP
|
||||||
precedence :left, :AND_OP
|
precedence :left, :AND_OP
|
||||||
|
@ -232,7 +232,6 @@ module Mm2ep
|
||||||
end
|
end
|
||||||
|
|
||||||
rule 'expr : VAR EQ_OP bool_expr' do |ex, v, _eq, n|
|
rule 'expr : VAR EQ_OP bool_expr' do |ex, v, _eq, n|
|
||||||
# binding.pry
|
|
||||||
ex.value = EqOp.new(
|
ex.value = EqOp.new(
|
||||||
VarValue.new(v.value.to_s, @names[v.value]),
|
VarValue.new(v.value.to_s, @names[v.value]),
|
||||||
BoolValue.new(n.value)
|
BoolValue.new(n.value)
|
||||||
|
|
1
spec/files/grammar_completely_invalid.txt
Normal file
1
spec/files/grammar_completely_invalid.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
false = "Arya"
|
1
spec/files/grammar_partially_invalid.txt
Normal file
1
spec/files/grammar_partially_invalid.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
( a_girl_has_no_name = true ) ANDAND ( character = "Arya Stark" ) OR false AND true
|
46
spec/mm2ep_depend/parser_spec.rb
Normal file
46
spec/mm2ep_depend/parser_spec.rb
Normal 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
|
|
@ -2,7 +2,6 @@ require 'spec_helper'
|
||||||
require 'mm2ep_depend'
|
require 'mm2ep_depend'
|
||||||
|
|
||||||
describe Mm2ep::Depend::Parser do
|
describe Mm2ep::Depend::Parser do
|
||||||
|
|
||||||
it 'has to do not before or' do
|
it 'has to do not before or' do
|
||||||
line = File.read(testfile('priority_not_or.txt')).delete("\n")
|
line = File.read(testfile('priority_not_or.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
|
@ -30,5 +29,4 @@ describe Mm2ep::Depend::Parser do
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,6 @@ require 'spec_helper'
|
||||||
require 'mm2ep_depend'
|
require 'mm2ep_depend'
|
||||||
|
|
||||||
describe Mm2ep::Depend::Parser do
|
describe Mm2ep::Depend::Parser do
|
||||||
|
|
||||||
it 'has to apply not on expr' do
|
it 'has to apply not on expr' do
|
||||||
line = File.read(testfile('simple_not_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_not_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
|
@ -62,8 +61,7 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'true',
|
parser.names = { 'truc_bidule' => 'true',
|
||||||
'machin' => 'true'
|
'machin' => 'true' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -72,8 +70,7 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'true',
|
parser.names = { 'truc_bidule' => 'true',
|
||||||
'machin' => 'false'
|
'machin' => 'false' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -82,8 +79,7 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'false',
|
parser.names = { 'truc_bidule' => 'false',
|
||||||
'machin' => 'true'
|
'machin' => 'true' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -92,8 +88,7 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_or_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'false',
|
parser.names = { 'truc_bidule' => 'false',
|
||||||
'machin' => 'false'
|
'machin' => 'false' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(false, token.compute)
|
assert_equal(false, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -102,8 +97,7 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'true',
|
parser.names = { 'truc_bidule' => 'true',
|
||||||
'machin' => 'true'
|
'machin' => 'true' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(true, token.compute)
|
assert_equal(true, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -112,8 +106,7 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'true',
|
parser.names = { 'truc_bidule' => 'true',
|
||||||
'machin' => 'false'
|
'machin' => 'false' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(false, token.compute)
|
assert_equal(false, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -122,8 +115,7 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'false',
|
parser.names = { 'truc_bidule' => 'false',
|
||||||
'machin' => 'true'
|
'machin' => 'true' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(false, token.compute)
|
assert_equal(false, token.compute)
|
||||||
end
|
end
|
||||||
|
@ -132,10 +124,8 @@ describe Mm2ep::Depend::Parser do
|
||||||
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
line = File.read(testfile('simple_expr_and_expr.txt')).delete("\n")
|
||||||
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
parser = Mm2ep::Depend::Parser.new(Mm2ep::Depend::Lexer.new)
|
||||||
parser.names = { 'truc_bidule' => 'false',
|
parser.names = { 'truc_bidule' => 'false',
|
||||||
'machin' => 'false'
|
'machin' => 'false' }
|
||||||
}
|
|
||||||
token = parser.parse(line.chomp)
|
token = parser.parse(line.chomp)
|
||||||
assert_equal(false, token.compute)
|
assert_equal(false, token.compute)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue