16
|
0 |
11 |
$self->{'grammar'} //= "\n content :\n ( comment | sentence )(s) /^\\Z/\n { +{ \$item[0] => \$item[1] } }\n | \n\n comment :\n /\\([^\\(\\)]*\\)/\n {\n \$item[1] =~ /\\(([^\\)]+)\\)/;\n +{ \$item[0] => ( \$1 || '' ) };\n }\n | \n\n sentence :\n command /[\\.;]\\s/\n { pop \@item; +{\@item} }\n | \n\n command :\n (\n say | set | append | add | subtract | multiply | divide |\n otherwise_if | if | otherwise | for\n )\n { +{\@item} }\n | \n\n say : /\\bsay\\b/ ( list | expression )\n { +{ \$item[0] => \$item[2] } }\n | \n\n set : /\\bset\\b/ object '=' ( list | expression )\n { +{ \$item[0] => [ \$item[2], \$item[4] ] } }\n | \n\n append : /\\bappend\\b/ ( list | expression ) '=' object\n { +{ \$item[0] => [ \$item[2], \$item[4] ] } }\n | \n\n add : /\\badd\\b/ expression '=' object\n { +{ \$item[0] => [ \$item[2], \$item[4] ] } }\n | \n\n subtract : /\\bsubtract\\b/ expression '`' object\n { +{ \$item[0] => [ \$item[2], \$item[4] ] } }\n | \n\n multiply : /\\bmultiply\\b/ object '~' expression\n { +{ \$item[0] => [ \$item[2], \$item[4] ] } }\n | \n\n divide : /\\bdivide\\b/ object '~' expression\n { +{ \$item[0] => [ \$item[2], \$item[4] ] } }\n | \n\n otherwise_if : /\\botherwise,\\s*if\\b/ expression '::' ( block | command )\n { +{ \$item[0] => { %{ \$item[2] }, %{ \$item[4] } } } }\n | \n\n if : /\\bif\\b/ expression '::' ( block | command )\n { +{ \$item[0] => { %{ \$item[2] }, %{ \$item[4] } } } }\n | \n\n otherwise : /\\botherwise\\b,?/ ( block | command )\n { +{ \$item[0] => \$item[2] } }\n | \n\n for : /\\bfor(?:\\s+each)?\\b/ object '=^' object block\n {\n +{\n \$item[0] => {\n item => \$item[2],\n list => \$item[4],\n %{ \$item[5] },\n }\n };\n }\n | \n\n block : '{{{' ( comment | sentence )(s?) '}}}'\n { +{ \$item[0] => \$item[2] } }\n | \n\n list :\n object ( list_item_seperator object )(s)\n { +{ shift \@item => [ shift \@item, \@{ \$item[0] } ] } }\n | \n\n list_item_seperator : /,\\s*(&&\\s+)?/\n | \n\n expression:\n object sub_expression(s?)\n { +{ \$item[0] => [ \$item[1], map { \@\$_ } \@{ \$item[2] } ] } }\n | \n\n sub_expression:\n operator object\n { [ \$item[1], \$item[2] ] }\n | \n\n operator :\n (\n '+' | '-' | '/' | '*' |\n '>=' | '>' | '<=' | '<' | '!\@=' | '\@=' | '!=' | '==' | '!^=' | '^=' |\n '&&' | '||'\n )\n {\n \$item[1] =\n ( \$item[1] eq '!\@=' ) ? 'not in' :\n ( \$item[1] eq '\@=' ) ? 'in' :\n ( \$item[1] eq '!^=' ) ? 'not begins' :\n ( \$item[1] eq '^=' ) ? 'begins' : \$item[1];\n +{\@item};\n }\n | \n\n object : call(s?) ( string | number | word | '=+' | '=-' )(s)\n {\n pop \@{ \$item[2] } while (\n \@{ \$item[2] } > 1 and\n \$item[2][-1]{word} =~ /^(?:value|string|text|number|list|array)\$/\n );\n\n for ( \@{ \$item[2] } ) {\n if ( \$_ eq '=+' ) {\n \$_ = { boolean => 'true' };\n }\n elsif ( \$_ eq '=-' ) {\n \$_ = { boolean => 'false' };\n }\n }\n\n my \$data = {};\n \$data->{calls} = \$item[1] if ( \@{\$item[1]} );\n \$data->{components} = \$item[2] if ( \@{\$item[2]} );\n\n +{ \$item[0] => \$data };\n }\n | \n\n call :\n ( '~=' | '\$=' | /\\[\\d+\\]/ )\n {\n \$item[1] =\n ( \$item[1] =~ /\\[(\\d+)\\]/ ) ? { 'item' => \$1 } :\n ( \$item[1] eq '~=' ) ? 'length' :\n ( \$item[1] eq '\$=' ) ? 'shift' : \$item[1];\n +{\@item};\n }\n | \n\n string :\n /\"[^\"]*\"/\n {\n \$item[1] =~ /\"([^\"]*)\"/;\n +{ \$item[0] => \$1 };\n }\n | \n\n number :\n /\\-?(?:\\d+,)*(?:\\d+\\.)*\\d+\\b/\n {\n \$item[1] =~ s/[^\\d\\.\\-]//g;\n +{\@item};\n }\n | \n\n word :\n /\\w+(?:'s)?\\b/\n { +{\@item} }\n | \n " |