-
-
Notifications
You must be signed in to change notification settings - Fork 26
Grammar
Alex Rakov edited this page Mar 4, 2019
·
15 revisions
ELENA uses LL(1) grammar. It is an analytical grammar, meaning that the role of the terminal token is defined by its position in the statement. As a result the grammar lacks the keywords ( instead user-defined attributes are used ) and there are no reserved words. For example, it is possible to write the code without attributes at all:
class
{
field;
method(param)
{
}
}
where a class with a name class is declared. It has one field with a name field and one method - method[1]
But in most cases it is required to provide additional info. So the token role is defined by its position.
class class;
singleton Tester
{
do(var class class)
{
}
}
public program()
{
var class class := new class();
Tester.do(class);
}
where class is used as an attribute to declare a new class, as a identifier type and as an identifier.
input ::=
{ input-element* new-line }*
input-element ::=
whitespace | comment | token
new-line ::=
Carriage return character (U+000D) followed by line feed character (U+000A)
| Line feed character (U+000A)
whitespace ::=
whitespace-character+
whitespace-character ::=
Horizontal tab character (U+0009)
| Space (U+0020)
comment ::=
single-line-comment
| delimited-comment
single-line-comment ::=
"//" input-character*
input-character ::=
Any Unicode character except a new-line-character
new-line-character ::=
Carriage return character (U+000D)
| Line feed character (U+000A)
delimited-comment ::=
"/*" delimited-comment-section* "*"+ "/"
delimited-comment-section ::=
not-asterisk
| "*"+ not-slash
not-asterisk ::=
Any Unicode character except *
not-slash ::=
Any Unicode character except /
token ::=
identifier
| reference
| integer-literal
| real-literal
| character-literal
| string-literal
| operator-literal
| operator-or-punctuator
| attribute-literal
identifier ::=
identifier-start-character identifier-part-character*
reference ::=
identifier { "'" identifier }+
identifier-start-character ::=
letter-character
| "_"
identifier-part-character ::=
letter-character
| decimal-digit-character
| "_"
letter-character ::=
A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl
decimal-digit-character ::=
A Unicode character of the class Nd
integer-literal ::=
decimal-digit+ integer-type-suffix?
real-literal ::=
decimal-digit+ "." decimal-digit+ exponent-part? real-type-suffix
character-literal ::=
"$" decimal-digit+
string-literal ::=
'"' string-character* '"'
| quote-escape-sequence
attribute-literal ::=
"#" hexadecimal-digit+
decimal-digit ::=
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
hexadecimal-digit ::=
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "A" | "B" | "C" | "D" | "E" | "F"
exponent-part ::=
"e" sign? decimal-digit+
sign ::=
"+"
| "-"
string-character ::=
Any character except "
| quote-escape-sequence
quote-escape-sequence ::=
'""'
integer-type-suffix ::=
"h" | "l"
real-type-suffix ::=
"r"
operator-literal ::=
$shr
| $shl
| $fnl
operator-or-punctuator ::=
"{"
| "}"
| "["
| "]"
| "("
| ")"
| "."
| ","
| ":"
| ";"
| "+"
| "-"
| "*"
| "/"
| "|"
| "\"
| "^"
| "!"
| "="
| "<"
| ">"
| "?"
| "&&"
| "||"
| "=="
| "!="
| "<="
| ">="
| "+="
| "-="
| "*="
| "/="
| "=>"
| ":="
| "[]"
module ::=
attribute_declaration* module_member*
attribute_declaration ::=
attribute-literal "=" identifier ";"
module_member-pattern ::=
visibility_attribute? property_attribute? scope_prefix_attribute? scope_attribute? type? identifier scope
module_member ::=
symbol_declaration
| class_declaration
symbol_declaration ::=
visibility? prefix? scope_attribute? identifier "=" expression ";"
visibility ::=
"public"
| "internal"
prefix ::=
"const"
| "preloaded"
scope_attribute ::=
"symbol"
| "static"
class_declaration ::=
visibility? attribute? prefix? scope_attribute? identifier template_parameters? class_body
class_body ::=
base_class? "{" class_member* "}"
| single_method
base_class ::=
":" { identifier | reference }
class_member ::=
field
| property
| constructor
| method
field ::=
field_attribute? field_prefix? field_attribute? {type | primitive}? identifier assigning_body? ";"
visibility ::=
"public"
| "internal"
attribute ::=
"sealed"
| "abstract"
| "closed"
field_attribute ::=
"sealed"
prefix ::=
"const"
field_prefix ::=
"const"
| "embeddable"
scope_attribute ::=
"class"
| "struct"
| "singleton"
| "interface"
| "mixin"
| "nonstructural"
field_attribute ::=
"field"
| "static"
template_parameters ::=
"<" template_parameter { "," template_parameter }* ">"
template_parameter ::=
{ identifier | reference } template_parameters?