Skip to content

Instantly share code, notes, and snippets.

@hsk
Last active August 29, 2015 14:21
Show Gist options
  • Save hsk/38facdec718dbab96a2d to your computer and use it in GitHub Desktop.
Save hsk/38facdec718dbab96a2d to your computer and use it in GitHub Desktop.
dachs language grammer

キーワード

true false do end var new begin let in as if unless then elseif else static_array pointer typeof ret case when for ensure init copy cast class import

symbol ::= expression の形式で文法要素を表します。( ... ) はグループを (^ ... ) は否定、|は選択、{ ... } は0回以上の繰り返し、{^ ... } が否定の0回以上の繰り返し、+ は1回以上の繰り返しを表します。

eol         ::= '\n' /* end of line */
eoi         ::= end of input
eps         ::= qi::eps
char        ::= *
alpha       ::= 'a' ... 'z' | 'A' ... 'Z'
alnum       ::= 'a' ... 'z' | 'A' ... 'Z' | '0' ... '9'

ascii_cntrl ::= acii::cntrl

bin         ::= '0' | '1'
oct         ::= '0' ... '7'
int         ::= ['-'] ('1' ... '9') {'0' ... '9'} | '0'
uint        ::= ('1' ... '9') {'0' ... '9'} | '0'
hex         ::= '0' ... '9' | 'a' ... 'f' | 'A' ... 'F'

sep         ::= (';' | eol | ';' eol)+

comma       ::= (',' [eol]) | ([eol] ',')
if_kind     ::= "if" | "unless"

trailing_comma
            ::= [',' | eol]

stmt_block_before_end
            ::= [compound_stmt {sep compound_stmt}]

program     ::= [sep]
                [definition {sep definition}] [sep]
                (eol | eoi)

definition  ::= converter
              | function_definition
              | constant_definition
              | class_definition
              | import

character_literal
            ::= '\''
              ( (^ ascii_cntrl | '\\' | '\'')
              | '\\' ('b' | 'f' | 'n' | 'r' | 't' | 'v' | 'e' | '0' | '\\' | '\'')
              ) '\''

float_literal
            ::= /* TODO */

boolean_literal
            ::= "true" | "false"

string_literal
            ::= '"'
                { (^ '"' | '\\' | ascii_cntrl)
                | '\\' ('b' | 'f' | 'n' | 'r' | 't' | 'v' | 'e'
                       | '\\' | '"'
                       | (^ ascii_cntrl)
                       )
                }
                '"'

integer_literal
            ::= "0x" hex | "0b" bin | "0o" oct | int

uinteger_literal
            ::= ("0x" hex | "0b" bin | "0o" oct | uint) 'u' (^ alnum | '_')

array_literal
            ::= '[' [[eol] typed_expr {comma typed_expr} trailing_comma] ']'

tuple_literal
            ::= '(' [[eol] typed_expr (comma typed_expr)+ trailing_comma] ')'

symbol_literal
            ::= ':' (alnum | '=' | '*' | '/' | '%' | '+' | '>' | '<' | '&' | '^' | '|' | '!' | '~' | '_' | '-')+

dict_literal::= '{' [[eol] (typed_expr "=>" typed_expr) {comma (typed_expr "=>" typed_expr)} trailing_comma] '}'

primary_literal
            ::= boolean_literal
              | character_literal
              | float_literal
              | uinteger_literal
              | integer_literal
            
called_function_name
            ::= ['@'] (alpha | '_') {alnum | '_'} ['?'] {'\''} ['!']

function_name
            ::= (alpha | '_') {alnum | '_'} ['?'] {'\''}

func_def_name
            ::= ternary_operator | binary_operator | unary_operator | function_name

variable_name
            ::= ['@'] (alpha | '_') {alnum | '_'} {'\''}

type_name   ::= variable_name

var_ref     ::= called_function_name

parameter   ::= "var" variable_name [[eol] ':' [eol] qualified_type]

constructor_call
            ::= ['{' [[eol] typed_expr {comma typed_expr} [eol]] '}']

object_construct
            ::= "new" qualified_type constructor_call [do_block]

lambda_expr_oneline
            ::= "->" [eol]
                ( '(' [parameter {comma parameter} trailing_comma] ')'
                  [':' qualified_type] [eol] "in"
                | [parameter {comma parameter} trailing_comma "in"]
                )
                [eol] typed_expr

lambda_expr_do_end
            ::= "->" [eol]
                ( '(' [parameter {comma parameter} trailing_comma] ')' [':' qualified_type]
                | [parameter {comma parameter}]
                ) [eol]
                "do" [eol]
                stmt_block_before_end [sep]
                "end"

lambda_expr ::= lambda_expr_do_end | lambda_expr_oneline
            
begin_end_expr
            ::= "begin" [eol] stmt_block_before_end [sep] "end"

let_expr    ::= "let" [eol]
                initialize_stmt {sep initialize_stmt} [eol]
                ( "in" [eol] typed_expr
                | "begin" [eol]
                  stmt_block_before_end [sep]
                  "end"
                )

primary_expr::= object_construct
              | lambda_expr
              | begin_end_expr
              | let_expr
              | primary_literal
              | string_literal
              | array_literal
              | symbol_literal
              | dict_literal
              | tuple_literal
              | var_ref
              | '(' [eol] typed_expr [eol] ')'
            
do_block    ::= "do"
                ['|' parameter {comma parameter} '|'] [eol]
                stmt_block_before_end [sep]
                "end"
              | '{'
                ['|' parameter {comma parameter} '|'] [eol]
                typed_expr [eol]
                '}'

var_ref_before_space
            ::= var_ref /*qi::no_skip[' ']*/ (^ "as")

postfix_expr::= primary_expr
                { [eol] '.' [eol] var_ref
                  '(' [typed_expr {comma typed_expr}] trailing_comma ')'
                  [do_block]
                | [eol] '.' [eol] var_ref_before_space
                  typed_exp {comma typed_exp}
                  do_block
                | [eol] '.' [eol] var_ref_before_space
                  (^ '+' | '-') (typed_expr % comma)
                | [eol] '.' [eol] var_ref do_block
                | [eol] '.' [eol] called_function_name
                | /*qi::no_skip[' ']*/ (^ "as") typed_expr {comma typed_expr} do_block
                | '[' [eol] typed_expr [eol] ']'
                | '(' [eol] [typed_expr {comma typed_expr}] trailing_comma ')' [do_block]
                }

unary_operator
            ::= "+" | "-" | "~" | "!"
            
binary_operator
            ::= ">>" | "<<" | "<=" | ">="
              | "==" | "!="
              | "&&" | "||"
              | "*"  | "/"  | "%"
              | "+"  | "-"
              | "<"  | ">"
              | "&"  | "^"  | "|"
              | "[]"

ternary_operator
            ::= "[]="

unary_expr  ::= unary_operator unary_expr
              | postfix_expr

cast_expr   ::= unary_expr    { [eol] "as"              [eol] qualified_type }
mult_expr   ::= cast_expr     { [eol] ("*" | "/" | "%") [eol] cast_expr }
additive_expr
            ::= mult_expr     { [eol] ("+" | "-")       [eol] mult_expr }
shift_expr  ::= additive_expr { [eol] ("<<" | ">>")     [eol] additive_expr }
relational_expr
            ::= shift_expr    { [eol] ("<=" | ">=" | "<" | ">") [eol] shift_expr }
equality_expr
            ::= relational_expr  { [eol] ("==" | "!=") [eol] relational_expr }
and_expr    ::= equality_expr    { [eol] "&"  [eol] equality_expr }
xor_expr    ::= and_expr         { [eol] "^"  [eol] and_expr }
or_expr     ::= xor_expr         { [eol] "|"  [eol] xor_expr }
logical_and_expr
            ::= or_expr          { [eol] "&&" [eol] or_expr }
logical_or_expr
            ::= logical_and_expr { [eol] "||" [eol] logical_and_expr }

range_expr  ::= logical_or_expr [[eol] ("..." | "..") [eol] logical_or_expr]

if_expr     ::= if_kind typed_expr
                ("then" | sep) typed_expr [sep]
                "else" [sep] typed_expr

typed_expr  ::= (if_expr | range_expr) [[eol] ':' [eol] qualified_type]

primary_type::= "static_array" ['(' [eol] qualified_type [eol] ')']
              | "pointer"      ['(' [eol] qualified_type [eol] ')']
              | type_name      ['(' [eol] qualified_type {comma qualified_type} [eol] ')']

nested_type ::= '(' [eol] qualified_type [eol] ')'
              | primary_type

array_type  ::= '[' [eol] qualified_type [eol] ']'

dict_type   ::= '{' [eol] qualified_type [eol] "=>" [eol]
                    qualified_type [eol]
                '}'

tuple_type  ::= '('
                [[eol] qualified_type (comma qualified_type)+ trailing_comma] 
                ')'

func_type   ::= "func" ['(' [[eol] qualified_type {comma qualified_type} trailing_comma] ')']
                [eol] ':' [eol] qualified_type
              | "proc" ['(' [[eol] qualified_type {comma qualified_type} trailing_comma] ')']

typeof_type ::= "typeof" '(' typed_expr ')'

compound_type
            ::= func_type | array_type | dict_type | tuple_type
              | typeof_type | nested_type

qualified_type
            ::= compound_type [qualifier]

assign_operator
            ::= '='
              | "*=" | "/=" | "%="
              | "+=" | "-="
              | "<<="| ">>="
              | "&=" | "^=" | "|="
              | "&&="| "||="

assignment_stmt
            ::= typed_expr {comma typed_expr} assign_operator typed_expr {comma typed_expr}

variable_decl
            ::= "var" variable_name [[eol] ':' [eol] qualified_type]
            
variable_decl_without_init
            ::= "var" variable_name [eol] ':' [eol] qualified_type

initialize_stmt
            ::= variable_decl {comma variable_decl} trailing_comma ":=" [eol]
                typed_expr {comma typed_expr}
              | variable_decl_without_init {comma variable_decl_without_init}

if_then_stmt_block
            ::= [compound_stmt {sep compound_stmt}]

if_else_stmt_block
            ::= [compound_stmt {sep compound_stmt}]

if_stmt     ::= if_kind typed_expr
                ("then" | sep) if_then_stmt_block [sep]
                { "elseif" typed_expr
                  ("then" | sep) if_then_stmt_block [sep]
                }
                ["else" [sep] if_else_stmt_block [sep]]
                "end"
            
return_stmt ::= "ret" [typed_expr {comma typed_expr}]

case_when_stmt_block
            ::= {compound_stmt sep}

case_stmt   ::= "case" sep
                ("when" typed_expr ("then" | sep)
                 case_when_stmt_block
                )+
                ["else" [sep] stmt_block_before_end [sep]]
                "end"

switch_stmt ::= "case" typed_expr sep
                ("when" typed_expr {comma typed_expr}
                 ("then" | sep) case_when_stmt_block
                )+ 
                ["else" [sep] stmt_block_before_end [sep]]
                "end"

for_stmt    ::= "for" parameter {comma parameter} "in" typed_expr sep
                stmt_block_before_end [sep]
                "end"
            

while_stmt  ::= "for" typed_expr ("do" | sep)
                stmt_block_before_end [sep]
                "end"

postfix_if_return_stmt
            ::= "ret" [typed_expr {comma typed_expr}]

postfix_if_stmt
            ::= ( postfix_if_return_stmt
                | assignment_stmt
                | typed_expr
                )
                if_kind typed_expr

do_stmt     ::= "do"
                [eol] stmt_block_before_end [sep]
                "end"

compound_stmt
            ::= if_stmt
              | case_stmt
              | switch_stmt
              | for_stmt
              | while_stmt
              | do_stmt
              | initialize_stmt
              | postfix_if_stmt
              | return_stmt
              | assignment_stmt
              | typed_expr

function_param_decls
            ::= ['(' [[eol] (parameter {comma parameter} trailing_comma] ')']

func_body_stmt_block
            ::= [compound_stmt {sep compound_stmt}]

function_definition
            ::= func_kind func_def_name function_param_decls
                [':' [eol] qualified_type] sep
                func_body_stmt_block [sep]
                ["ensure" sep stmt_block_before_end [sep]]
                "end"

constant_decl
            ::= variable_name [':' [eol] qualified_type]

constant_definition
            ::= constant_decl {comma constant_decl} trailing_comma ":=" [eol]
                typed_expr {comma typed_expr}

class_name  ::= (alpha | '_') {alnum | '_'}

access_specifier
            ::= eps ["+" | "-"]

instance_variable_decl
            ::= variable_name [[eol] ':' [eol] qualified_type]

instance_variable_decls
            ::= instance_variable_decl {([eol] ',') instance_variable_decl}

method_definition
            ::= access_specifier function_definition

constructor ::= "init" function_param_decls sep
                stmt_block_before_end [sep]
                "end"

copier      ::= "copy" sep func_body_stmt_block [sep] "end"

converter   ::= "cast" function_param_decls
                ':' [eol] qualified_type sep
                func_body_stmt_block [sep] "end"

class_definition
            ::= "class" class_name
                { sep ( method_definition
                      | constructor
                      | copier
                      | converter
                      | instance_variable_decls
                      )
                } sep "end"

import      ::= "import" ((alnum | '_')+ {'.' (alnum | '_')+})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment