Permalink
Switch branches/tags
Find file
Fetching contributors…
Cannot retrieve contributors at this time
107 lines (78 sloc) 2.67 KB
require 'minitest/autorun'
require 'kpeg'
require 'kpeg/format_parser'
require 'kpeg/code_generator'
require 'stringio'
class TestKpegGrammar < Minitest::Test
LEFT_RECURSION = <<-'STR'
name = name:n "[]" { [:array, n] }
| < /\w+/ > { [:word, text] }
root = name
STR
def test_left_recursion_invoke_rule_directly
parc = KPeg::FormatParser.new(LEFT_RECURSION)
assert parc.parse, "Unable to parse"
gram = parc.grammar
# gr = KPeg::GrammarRenderer.new(gram)
# puts
# gr.render(STDOUT)
cg = KPeg::CodeGenerator.new "TestCalc", gram
code = cg.make("blah[]")
assert_equal true, code.parse("name")
assert_equal [:array, [:word, "blah"]], code.result
end
def test_left_recursion_invoke_rule_via_another
parc = KPeg::FormatParser.new(LEFT_RECURSION)
assert parc.parse, "Unable to parse"
gram = parc.grammar
# gr = KPeg::GrammarRenderer.new(gram)
# puts
# gr.render(STDOUT)
cg = KPeg::CodeGenerator.new "TestCalc", gram
code = cg.make("blah[]")
assert_equal true, code.parse("root")
assert_equal [:array, [:word, "blah"]], code.result
end
def test_gen_calc
parc = KPeg::FormatParser.new(<<-'STR')
Stmt = - Expr:e EOL { @answers << e }
| ( !EOL . )* EOL { puts "error" }
Expr = ID:i ASSIGN Sum:s { @vars[i] = s }
| Sum:s { s }
Sum = Product:l
( PLUS Product:r { l += r }
| MINUS Product:r { l -= r }
)* { l }
Product = Value:l
( TIMES Value:r { l *= r }
| DIVIDE Value:r { l /= r }
)* { l }
Value = NUMBER:i { i }
| ID:i !ASSIGN { @vars[i] }
| OPEN Expr:i CLOSE { i }
NUMBER = < [0-9]+ > - { text.to_i }
ID = < [a-z] > - { text }
ASSIGN = '=' -
PLUS = '+' -
MINUS = '-' -
TIMES = '*' -
DIVIDE = '/' -
OPEN = '(' -
CLOSE = ')' -
- = (' ' | '\t')*
EOL = ('\n' | '\r\n' | '\r' | ';') -
root = Stmt+
STR
assert parc.parse, "Unable to parse"
gram = parc.grammar
# gr = KPeg::GrammarRenderer.new(gram)
# puts
# gr.render(STDOUT)
cg = KPeg::CodeGenerator.new "TestCalc", gram
code = cg.make("i = 3+4; j = i*8; i + j * 2;")
code.instance_variable_set(:@vars, {})
code.instance_variable_set(:@answers, [])
assert_equal true, code.parse
assert_equal [7,56,119], code.instance_variable_get(:@answers)
end
end