﻿//----------------------- Programos struktĆ…Ā«ra ------------------------
<program>      ::=     <imports> (<mainClass> | <class> ) | (<mainClass> | <class> )

<imports>      ::=     <import> <imports> | <import>
<import>       ::=     'import' <path_to_class> ';'

<path_to_class>::=     <string>

<mainClass>    ::=     'class' <className> '{' <mainClassBody> '}'
<mainClassBody>::=     <fields> 'void main()' <block> | <fields> 'void main()' <block> <classBody> | 'void main()' <block> |'void main()' <block> <classBody>

<class>        ::=     'class' <className> '{' <classBody> '}'
<classBody>    ::=     <functions>

<className>    ::=     <letters>

<block>        ::=     '{' <statements> '}'

//------------------------- FuncijĆ…Ā³ struktĆ…Ā«ra ----------------------

<functions>	   ::=	   <function> <functions> | <function>		
<function>     ::=     <returnType> <functionName> '(' <parameters> ')' <block> | <returnType> <functionName> '(' ')' <block>

<parameters>    ::=     <parameter> ',' <parameters> | <parameter>
<parameter>     ::=     <type> <variable>

<functionName>   ::=     <letters>

//------------------------- Statements ---------------------

<statements>       ::=     <statement> ';' <statements> | <statement> ';'
<statement>        ::=     <simpleStmt> | <controlStmt> | <functionCall> | <statement_return>

<simpleStmt>       ::=     <statement_varDeclaration> | <statement_assignment> | <io>
<controlStmt>      ::=     <loop_for> | <loop_while> | <statement_if>
<functionCall>     ::=     <functionName> '(' <callParameters> ')' | <functionName> '(' ')' | <className> '.' ( <functionName> '(' <callParameters> ')' | <functionName> '(' ')')
<callParameters>   ::=     <expression> ',' <callParameters> | <expression>

<statement_if>     ::=     'if' ( <expression> ) <block> | 'if' <expression> <block> 'else' <block> | <statement_if> 

<statement_return> ::=     'return ' <expression> | 'return 0'

---------------------- Simple Statments -----------------

<fields>                    ::=     <field> <fields> | <field>
<field>                     ::=     <statement_varDeclaration>

<statement_varDeclaration>  ::=     <type> <variable>  '=' <expression> | <type> <variable> | <className> <variable>
<statement_assignment>      ::=     <variable> <assigmentOp> <expression>

<io>         ::=     <input> | <output>
<input>      ::=     'read' <variable>
<output>     ::=     'write' <expression>

---------------------- Loops ----------------

<loop_for>         ::=     'for' '(' <expression> ';' <expression>' ';' <expression>) <block>
<loop_while>       ::=     'while' '(' <expression> ')' <block>

------------------------ Expressions --------------------

<expression>      ::=     <logical_and_exp> <or> <expression> | <logical_and_exp>
<logical_and_exp> ::=     <compare_exp> <and> <logical_and_exp> | <compare_exp>
<compare_exp>     ::=     <add_exp> <comparison> <compare_exp> | <add_exp>
<add_exp>         ::=     <term> <add_op> <add_exp> | <term>
<term>            ::=     <factor> <mult_op> <term> | <factor>
<factor>          ::=     '(' <expression> ')' | <variable> | <number> | <constant> | <boolean> | <functionCall> | <expression> 

-------------------- Types, etc.--------------------------
<type>         ::=     'int' | 'float' | 'string' | 'bool'
<returnType>   ::=     <type> | 'void'

<number>       ::=     <negativeSign> (<int> | <float>) | (<int> | <float>)
<int>          ::=     <digits>
<float>        ::=     <int> '.' <digits>

<variable>     ::=     <letters>
 
<negativeSign> ::=     '-'
<digits>       ::=     <digit> <digits> | <digit>
<digit>        ::=     '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
<letters>      ::=     <letter> <letters> | <letter>
<letter>       ::=     'a' | 'b' | ... | 'z' | 'A' | 'B' | ... | 'Z'

<not>          ::=     '!'
<and>          ::=     '&&'
<or>           ::=     '||'
<comparison>   ::=     '<' | '<=' | '>' | '>=' | '!=' | '=='
<add_op>       ::=     '+' | '-'
<mult_op>      ::=     '*' | '/'
<assigmentOp>  ::=     '=' | '-=' | '+=' | '*='

<string>       ::=     '"' ( <symbol> <string> | <symbol> ) '"'
<symbol>       ::=     anySymbolExceptDoubleQuote | '\"'

<boolean>      ::=     'true' | 'false'
<constant>     ::=     <string> | <number>