more basics rolling home

This commit is contained in:
Torsten Ruger 2015-08-29 16:08:28 +03:00
parent fa27ebebdf
commit 4b82189255
3 changed files with 26 additions and 89 deletions

View File

@ -11,82 +11,23 @@ grammar BasicTypes
"#" (/.*/ !linebreak) linebreak "#" (/.*/ !linebreak) linebreak
end end
rule dot '.' end rule name_expression
(name:([a-z_] [a-zA-Z0-9_]*) space?) { Ast::NameExpression.new(capture(:name).to_str)}
## Lexical syntax
rule number
float | integer
end
rule float
(digits '.' digits space*) { to_str.to_f }
end
rule integer
(digits space*) { to_str.to_i }
end end
rule digits rule digits
[0-9]+ ('_' [0-9]+)* # Numbers may contain underscores. [0-9] [0-9]*
end end
rule lparen '(' space* end rule integer_expression
rule rparen ')' space* end (digits space?) { Ast::IntegerExpression.new(to_str.to_i) }
# Hierarchical syntax
rule term
additive | factor
end end
rule additive rule instance_variable
(factor operator:('+' | '-') space* term) { ('@' ivar:name_expression) { Ast::VariableExpression.new (capture(:ivar).value).name }
capture(:factor).value.send(capture(:operator).to_s, capture(:term).value)
}
end end
rule factor rule basic_expression
multiplicative | prefix name_expression | integer_expression | instance_variable
end end
rule multiplicative
(prefix operator:('*' | '/' | '%') space* factor) {
capture(:prefix).value.send(capture(:operator).to_s, capture(:factor).value)
}
end
rule prefix
prefixed | exponent
end
rule prefixed
(operator:('-' | '+' | '~') space* prefix) {
s = capture(:operator).to_s
s += '@' unless s == '~' # Unary + and - require an @.
capture(:prefix).value.send(s)
}
end
rule exponent
exponential | primary
end
rule exponential
(primary operator:'**' space* prefix) {
capture(:primary).value.send(capture(:operator).to_s, capture(:prefix).value)
}
end
rule primary
group | number
end
rule group
(lparen term rparen) {
capture(:term).value
}
end
end end

View File

@ -35,7 +35,7 @@ grammar Keywords
end end
rule keyword_expression rule keyword_expression
keyword_true | keyword_false | keyword_nil keyword_true | keyword_false | keyword_nil | basic_expression
end end
root keyword_expression root keyword_expression

View File

@ -1,9 +1,7 @@
require_relative "../setup" require_relative "../setup"
class TestBasic < MiniTest::Test class TestBasic < MiniTest::Test
# include the magic (setup and parse -> test method translation), see there #test basics and keyword expressions. Keywords includes BasicTypes
#include ParserHelper
def setup def setup
@parser = Keywords @parser = Keywords
end end
@ -32,43 +30,41 @@ class TestBasic < MiniTest::Test
check check
end end
def ttest_number def test_integer
@input = '42 ' @input = '42 '
@output = Ast::IntegerExpression.new(42) @output = Ast::IntegerExpression.new(42)
@root = :integer check
end end
def ttest_name def test_name
@input = 'foo ' @input = 'foo '
@output = Ast::NameExpression.new('foo') @output = Ast::NameExpression.new('foo')
@root = :name check
end end
def ttest_name_underscode_start def test_name_underscode_start
@input = '_bar ' @input = '_bar '
@output = Ast::NameExpression.new('_bar') @output = Ast::NameExpression.new('_bar')
@root = :name check
end end
def ttest_name_underscode_middle def test_name_underscode_middle
@input = 'foo_bar ' @input = 'foo_bar '
@parse_output = {:name => 'foo_bar'}
@output = Ast::NameExpression.new('foo_bar') @output = Ast::NameExpression.new('foo_bar')
@root = :name check
end end
def ttest_instance_variable def test_instance_variable
@input = '@foo_bar ' @input = '@foo_bar '
@parse_output = {:instance_variable=>{:name=>"foo_bar"}}
@output = Ast::VariableExpression.new(:foo_bar) @output = Ast::VariableExpression.new(:foo_bar)
@root = :instance_variable check
end end
def ttest_module_name def ttest_module_name
@input = 'FooBar ' @input = 'FooBar '
@parse_output = {:module_name=>"FooBar"} @parse_output = {:module_name=>"FooBar"}
@output = Ast::ModuleName.new("FooBar") @output = Ast::ModuleName.new("FooBar")
@root = :module_name check
end end
def ttest_comment def ttest_comment
@ -76,14 +72,14 @@ class TestBasic < MiniTest::Test
@input = out.dup #NEEDS the return, which is what delimits the comment @input = out.dup #NEEDS the return, which is what delimits the comment
@parse_output = out @parse_output = out
@output = @parse_output #dont transform @output = @parse_output #dont transform
@root = :comment check
end end
def ttest_string def ttest_string
@input = "\"hello\"" @input = "\"hello\""
@parse_output = {:string=>[{:char=>"h"}, {:char=>"e"}, {:char=>"l"}, {:char=>"l"}, {:char=>"o"}]} @parse_output = {:string=>[{:char=>"h"}, {:char=>"e"}, {:char=>"l"}, {:char=>"l"}, {:char=>"o"}]}
@output = Ast::StringExpression.new('hello') @output = Ast::StringExpression.new('hello')
@root = :string check
end end
def ttest_string_escapes def ttest_string_escapes
@ -92,7 +88,7 @@ class TestBasic < MiniTest::Test
@parse_output = {:string=>[{:char=>"h"}, {:char=>"e"}, {:char=>"l"}, {:char=>"l"}, {:char=>"o"}, @parse_output = {:string=>[{:char=>"h"}, {:char=>"e"}, {:char=>"l"}, {:char=>"l"}, {:char=>"o"},
{:char=>" "}, {:char=>" "}, {:esc=>"n"}, {:char=>"y"}, {:char=>"o"}, {:char=>"u"}]} {:char=>" "}, {:char=>" "}, {:esc=>"n"}, {:char=>"y"}, {:char=>"o"}, {:char=>"u"}]}
@output = Ast::StringExpression.new(out) @output = Ast::StringExpression.new(out)
@root = :string check
end end
end end