Skip to content
Hiroshi Sakurai edited this page Nov 11, 2017 · 37 revisions

Clover2 構文

拡張BNFで構文を書きます。

parse_word_and_slash ::= ('./' | '../')? alpha (alpha | '_' | '/')*
parse_word ::= alpha (alpha | '_')*
parse_simple_lambda_params ::= ('|' parse_params_and_entry_to_lvtable (':' parse_type )?)? parse_block
parse_method_params ::= '(' (expression '@' (alpha | '_')* (',' expression '@' (alpha | '_')*)*)? ')' ('{' parse_simple_lambda_params)?

parse_command_method_params ::= ";" | "\n" | 
        while(1) {

            while(1) {
                if('$') {
                    if('{') {

                        while(1) {
                            if(*info->p == '}') {
                                info->p++;
                                break;
                            }
                            else if(*info->p == '\0') {
                                parser_err_msg(info, "require } to close ${ENV}");
                                info->err_num++;
                                break;
                            }
                            else {
                                sBuf_append_char(&env_name, *info->p);
                                info->p++;
                            }
                        }
                    }
                    else {
                        while(isalnum(*info->p) || *info->p == '_') {
                            sBuf_append_char(&env_name, *info->p);
                            info->p++;
                        }
                    }
                }
                | '\\' .
                | '"'
                | '\'') {
                    info->p++;
                    squort = !squort;
                }
                else if(squort || dquort) {
                    sBuf_append_char(&param, *info->p);
                    info->p++;
                }
                else if(*info->p == ' ' || *info->p == '\t' || *info->p == '\n' || *info->p == ';' || *info->p == '\0' || *info->p == '|' || *info->p == '&') 
                {
                    break;
                }
                else {
                    sBuf_append_char(&param, *info->p);
                    info->p++;
                }
            }

            if(*info->p == '\0' || *info->p == '\n' || *info->p == ';' 
                || *info->p == '|' || *info->p == '&') 
            {
                break;
            }
        }
    }

get_number ::= ('0'|...|'9')+ '.' ('0'|...|'9')+ ('f' | 'F')?
             | ('0'|...|'9')+ ('y' | 'uy' | 's' | 'us' | 'l' | 'ul' | 'u')?

get_hex_number ::= '0x' ('0'|...|'9'|'a'|...|'f'|'A'|...|'F')+ ('y' | 'uy' | 's' | 'us' | 'l' | 'ul' | 'u')?
get_oct_number ::= '0' ('0'|...|'7')* ('y' | 'uy' | 's' | 'us' | 'l' | 'ul' |'u')?

if_expression ::= "(" expression ")" "{" parse_block
                  ("elif" "(" expression ")" "{" parse_block)*
                  ("else" "{" parse_block)?
while_expression ::= "(" expression ")" "{" parse_block
for_expression ::= "(" expression ";" expression ";" expression ")" "{" parse_block
return_expression ::= /* empty */ | expression
new_expression ::= parse_type_for_new parse_method_params

throw_expression ::= expression

parse_param ::= parse_word ":" parse_type

parse_params0 ::= (parse_param ("," parse_param)*)? ")" 
parse_params1 ::= (parse_param ("," parse_param)*)? "|"

parse_params_and_entry_to_lvtable0 ::= parse_params0
parse_params_and_entry_to_lvtable1 ::= parse_params1

try_expression ::= "{" parse_block "catch" "(" parse_params_and_entry_to_lvtable0 "{" parse_block
parse_class_type ::= parse_word
parse_type ::= "lambda" ( '(' (parse_type (',' parse_type)*)? ')' )?
                (':' parse_type)? '[]'? ('@' (alpha (alpha | num | '-' | '_' | '[' | ']')* )?)?
              | parse_word ('<' parse_type (',' parse_type)* '>'
                '[]'? ('@' (alpha (alpha | num | '-' | '_' | '[' | ']')* )?)?
parse_type_for_new ::= parse_word ('<' parse_type (',' parse_type)* '>')? ('[' expression "]")?
assign_operator ::= "+=" expression
                  | "-=" expression
                  | "*=" expression
                  | "/=" expression
                  | "%=" expression
                  | "<<=" expression
                  | ">>=" expression
                  | "&=" expression
                  | "^=" expression
                  | "|=" expression

postposition_operator ::=
  ( '..' parse_word (('(' | '{') parse_method_params | assign_operator | '==' expression )?
  | '[' expression "]" (assign_operator | '==' expression)?
  | '->' parse_type ('==' expression)?
  | '++'
  | '--'
  )*

parse_block_object ::= parse_params_and_entry_to_lvtable0 (':' parse_type)? "{" parse_block 
parse_function ::= parse_word "(" parse_params_and_entry_to_lvtable0 (':' parse_type)? "{" parse_block
parse_normal_block ::= parse_block
parse_array_value ::= ']' | expression (',' expression)* ']'
parse_carray_value ::= '}' | expression (',' expression)* '}'
parse_equalable_carray_value ::= '}' | expression (',' expression)* '}'
parse_sortable_carray_value ::= '}' | expression (',' expression)* '}'
parse_hash_value ::= '}' | expression ":" expression (',' expression ":" expression)* '}'
parse_list_value ::= '}' | expression (',' expression)* '}'
parse_equalable_list_value ::= '}' | expression (',' expression)* '}'
parse_sortable_list_value ::= '}' | expression (',' expression)* '}'
parse_tuple_value ::= '}' | expression (',' expression)* '}'
parse_iniherit ::= parse_method_params
parse_string_expression ::= '{' expression '}'

expression_node ::=
      "-" get_number_TRUE
    | "+" get_number_FALSE
    | "0x" get_hex_number
    | "0" get_oct_number
    | get_number_FALSE
    | '"' {not '"' | "\\" .} '"'
    | ("B"|"b") '"' {not '"' | '\\0' | '\\n' | '\\t' | '\\r'  | '\\a' | '\\\\' | parse_string_expression | .} '"'
    | ("P"|"p") '"' {not '"' | '\\0' | '\\n' | '\\t' | '\\r'  | '\\a' | '\\\\' | parse_string_expression | .} '"'
    | "'\\n'"
    | "'\\t'"
    | "'\\r'"
    | "'\\a'"
    | "'\\\\'"
    | "'\\0'"
    | "'\\" . "'"
    | "'" [0 - 127] "'"
    | "'" utf8 "'"
    | '[' parse_array_value
    | '{' parse_normal_block
    | "if" if_expression
    | "while" while_expression
    | "for" for_expression
    | "break"
    | "true"
    | "false"
    | "null"
    | "throw" throw_expression
    | "try" try_expressio
    | "return" return_expression
    | "new" new_expression
    | "closure" '(' parse_block_object
    | "lambda" '(' parse_block_object
    | "def" parse_function
    | "inherit" parse_iniherit
    | "list" '{' parse_list_value
    | ("equalable_list" | "elist") '{' parse_equalable_list_value
    | ("sortable_list" | "slist") '{' parse_sortable_list_value
    | "tuple" '{' parse_tuple_value
    | "hash" '{' parse_hash_value
    | "array" '{' parse_carray_value
    | ("equalable_array" | "earray") '{' parse_equalable_carray_value
    | ("sortable_array" | "sarray" '{' parse_sortable_carray_value
    | parse_word_and_slash ':=' expression
    | parse_word_and_slash ':' parse_type '=' expression
    | parse_word_and_slash '=' expression
    | parse_word_and_slash assign_operator
    | parse_word_and_slash parse_type '.' parse_word parse_method_params
    | parse_word_and_slash parse_type '.' parse_word assign_operator
    | parse_word_and_slash parse_type '.' parse_word '==' expression
    | parse_word_and_slash parse_method_params
    | parse_word_and_slash parse_command_method_params { "||" parse_word parse_command_method_params | "&&" | ";" | "\n" }
    | parse_word_and_slash
    | "/" { "\\{" | "\{" parse_string_expression | not "/" }  "/" {"g" | "i" | "s" | "m" | "A" | "D" | "U" | "x" }
    | '(' expression ")"
    | '&' expression

expression_monadic_operator ::= ("++"|"--"|"~"|"!") expression_monadic_operator
                              | expression_node postposition_operator
expression_implements ::= expression_monadic_operator {"implements" parse_word}
expression_mult_div ::= expression_implements {("*"|"/"|"%") expression_implements}
expression_add_sub ::= expression_mult_div {("+"|"-") expression_mult_div}
expression_shift ::= expression_add_sub {("<<=" | ">>=") expression_add_sub}
expression_comparison_operator ::= expression_shift {(">=" | "<=" | ">>" | "<<") expression_shift}
expression_comparison_equal_operator ::= expression_comparison_operator {("=="|"!=") expression_comparison_operator}
expression_and ::= expression_comparison_equal_operator {"&" expression_comparison_equal_operator}
expression_xor ::= expression_and {"^" expression_and}
expression_or ::= expression_xor {"|" expression_xor}
expression_and_and_or_or ::= expression_or {("&&" | "||") expression_and_and_or_or}
expression_conditional_operator ::= expression_and_and_or_or {"?" expression ":" expression }
expression ::= expression_conditional_operator

Clone this wiki locally