248 lines
6.3 KiB
Plaintext
248 lines
6.3 KiB
Plaintext
|
|
grammar Bosl
|
|
|
|
# unicode generalized categories , according to regex ruby page
|
|
rule lower /[[:lower:]]/ end # Lowercase alphabetical character
|
|
rule upper /[[:upper:]]/ end # Uppercase alphabetical
|
|
rule alnum /[[:alnum:]]/ end # Alphabetic and numeric character
|
|
rule alpha /[[:alpha:]]/ end # Alphabetic character
|
|
rule blank /[[:blank:]]/ end # Space or tab
|
|
rule space /[[:space:]]/ end # Whitespace character ([:blank:], newline, carriage return, etc.)
|
|
rule digit /[[:digit:]]/ end # Digit
|
|
rule graph /[[:graph:]]/ end # Non-blank character (excludes spaces, control characters, and similar)
|
|
rule print /[[:print:]]/ end # Like [:graph:], but includes the space character
|
|
rule xdigit /[[:xdigit:]]/ end # Digit allowed in a hexadecimal number (i.e., 0-9a-fA-F)
|
|
|
|
rule linebreak (!blank space) end #define in regex terms for utf
|
|
|
|
rule comment #don't include the newline (which ends the comment)
|
|
"#" /.*/
|
|
end
|
|
|
|
rule name_expression
|
|
(name:([a-z_] [a-zA-Z0-9_]*) space*) { Ast::NameExpression.new(capture(:name).to_str)}
|
|
end
|
|
|
|
rule module_name_expression
|
|
(name:([A-Z] [a-zA-Z0-9_]*) space*) { Ast::ModuleName.new(capture(:name).to_str)}
|
|
end
|
|
|
|
rule digits
|
|
[0-9] [0-9]*
|
|
end
|
|
|
|
rule integer_expression
|
|
(digits space*) { Ast::IntegerExpression.new(to_str.to_i) }
|
|
end
|
|
|
|
rule string_expression
|
|
#"'" (/.*/ !"'") "'"
|
|
('"' str:(!'"' .)* '"') {Ast::StringExpression.new(capture(:str).to_str) }
|
|
end
|
|
|
|
rule basic_expression
|
|
name_expression | integer_expression |
|
|
module_name_expression | string_expression
|
|
end
|
|
|
|
rule keyword_begin 'begin' space* end
|
|
rule keyword_class 'class' space* end
|
|
rule keyword_def 'def' space* end
|
|
rule keyword_do 'do' space* end
|
|
rule keyword_else 'else' space* end
|
|
rule keyword_end 'end' space* end
|
|
rule keyword_if 'if' end
|
|
rule keyword_rescue 'rescue' space* end
|
|
rule keyword_return 'return' space* end
|
|
rule keyword_module 'module' space* end
|
|
rule keyword_unless 'unless' space* end
|
|
rule keyword_until 'until' space* end
|
|
rule keyword_while 'while' space* end
|
|
|
|
rule keyword_nil
|
|
('nil' space* ){ Ast::NilExpression.new }
|
|
end
|
|
|
|
rule keyword_false
|
|
('false' space*) { Ast::FalseExpression.new }
|
|
end
|
|
|
|
rule keyword_true
|
|
('true' space*) { Ast::TrueExpression.new }
|
|
end
|
|
|
|
# this rule is just to make sure identifiers can't be keywords. Kind of duplication here, but we need the
|
|
# space in above rules, so just make sure to add any here too.
|
|
rule keyword ('begin' | 'def' | 'do' | 'else' | 'end' |
|
|
'false' | 'if' | 'rescue' | 'true' | 'nil' |
|
|
'unless' | 'until' | 'while') space*
|
|
end
|
|
|
|
rule keyword_expression
|
|
keyword_true | keyword_false | keyword_nil | basic_expression
|
|
end
|
|
|
|
|
|
# Tokens are single or double character combinations with "meaning"
|
|
# braces, comman, point, questionmark , quotes, that kind of thing
|
|
# operator symbols are separate in Opreators
|
|
|
|
rule left_parenthesis
|
|
'(' space*
|
|
end
|
|
|
|
rule right_parenthesis
|
|
')' space*
|
|
end
|
|
|
|
rule left_brace
|
|
'{' space*
|
|
end
|
|
|
|
rule right_brace
|
|
'}' space*
|
|
end
|
|
|
|
rule left_bracket
|
|
'[' space*
|
|
end
|
|
|
|
rule right_bracket
|
|
']' space*
|
|
end
|
|
|
|
rule association
|
|
"=>" space*
|
|
end
|
|
|
|
rule comma
|
|
',' space*
|
|
end
|
|
|
|
rule colon
|
|
':' space*
|
|
end
|
|
|
|
rule semicolon
|
|
';' space*
|
|
end
|
|
|
|
rule question_mark
|
|
'?' space*
|
|
end
|
|
|
|
rule excamation_mark
|
|
'!' space*
|
|
end
|
|
|
|
rule more_args
|
|
(comma basic_expression )* {
|
|
captures(:basic_expression).collect{|u| u.value }
|
|
}
|
|
end
|
|
|
|
rule argument_list
|
|
(left_parenthesis basic_expression? more_args right_parenthesis){
|
|
args = [ ]
|
|
args << capture(:basic_expression).value if capture(:basic_expression)
|
|
args += capture(:more_args).value if capture(:more_args)
|
|
args
|
|
}
|
|
end
|
|
|
|
rule call_site
|
|
(field_expression argument_list space?) {
|
|
Ast::CallSiteExpression.new(capture(:field_expression).value ,
|
|
capture(:argument_list).value )
|
|
}
|
|
end
|
|
|
|
rule field_expression
|
|
(basic_expression "." name_expression space?) {
|
|
Ast::FieldExpression.new(capture(:basic_expression).value ,
|
|
capture(:name_expression).value.name )
|
|
}
|
|
end
|
|
|
|
rule value_expression
|
|
call_site | basic_expression
|
|
end
|
|
|
|
rule function_definition
|
|
keyword_def name:function_name parameter_list newline expressions_end newline
|
|
end
|
|
|
|
rule parameter_list
|
|
left_parenthesis parameter_list:( name:parameter? (comma name:parameter)* ) right_parenthesis
|
|
end
|
|
|
|
rule more_typed_args
|
|
(comma typed_arg )* {
|
|
captures(:typed_arg).collect{|u| u.value }
|
|
}
|
|
end
|
|
|
|
rule typed_argument_list
|
|
(left_parenthesis typed_arg? more_typed_args right_parenthesis){
|
|
args = [ ]
|
|
args << capture(:typed_arg).value if capture(:typed_arg)
|
|
args += capture(:more_typed_args).value if capture(:more_typed_args)
|
|
args
|
|
}
|
|
end
|
|
|
|
rule type
|
|
(typ:("int" | "ref") space*) { capture(:typ).to_s }
|
|
end
|
|
|
|
rule typed_arg
|
|
(type name_expression) {
|
|
Ast::TypedName.new(capture(:type).value , capture(:name_expression).value.name)
|
|
}
|
|
end
|
|
|
|
rule variable_definition
|
|
(typed_arg ("=" space* value_expression)?) {
|
|
type = capture(:typed_arg).value
|
|
value = capture(:value_expression) ? capture(:value_expression).value : nil
|
|
var = Ast::VariableDefinition.new(type.type , type.name , value)
|
|
}
|
|
end
|
|
|
|
rule assignment
|
|
(name_expression "=" space* value_expression){
|
|
Ast::AssignmentExpression.new( capture(:name_expression).value.name , capture(:value_expression).value)
|
|
}
|
|
end
|
|
|
|
rule conditional
|
|
(keyword_if left_parenthesis value_expression right_parenthesis
|
|
body
|
|
keyword_end) {
|
|
Ast::IfExpression.new( capture(:value_expression).value , capture(:body).value , nil)
|
|
}
|
|
end
|
|
|
|
rule while
|
|
keyword_while left_parenthesis value_expression right_parenthesis keyword_do
|
|
body
|
|
keyword_end
|
|
end
|
|
|
|
rule return
|
|
keyword_return value_expression newline
|
|
end
|
|
|
|
rule body
|
|
(statement+){
|
|
captures(:statement).collect{|u| u.value }
|
|
}
|
|
end
|
|
|
|
rule statement
|
|
conditional | while | return | variable_definition | assignment | call_site
|
|
end
|
|
|
|
|
|
end
|