Skip to content
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.

Lexical grammar

input ::=
   { input-element* new-line }*

input-element ::=
    whitespace | comment | token

Line terminators

new-line ::=
   Carriage return character (U+000D) followed by line feed character (U+000A) 
   | Line feed character (U+000A)

White space

whitespace ::=
   whitespace-character+  

whitespace-character ::=
   Horizontal tab character (U+0009)
   | Space (U+0020)

Comments

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 /

Tokens

token ::=
   identifier
   | reference
   | integer-literal
   | real-literal
   | character-literal
   | string-literal
   | operator-literal
   | operator-or-punctuator
   | attribute-literal

Identifiers and References

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

Literals

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"

Operators

operator-literal ::=
   $shr
   | $shl
   | $fnl

operator-or-punctuator ::=
   "{"
   | "}"
   | "["
   | "]"
   | "("
   | ")"
   | "."
   | ","
   | ":"
   | ";"
   | "+"
   | "-"
   | "*"
   | "/"
   | "|"
   | "\"
   | "^"
   | "!"
   | "="
   | "<"
   | ">"
   | "?"
   | "&&"
   | "||"
   | "=="
   | "!="
   | "<="
   | ">="
   | "+="
   | "-="
   | "*="
   | "/="
   | "=>"
   | ":="
   | "[]"       

Syntactic grammar

Syntactic grammar

module ::=
   attribute_declaration* module_member*

Attribute declaration

attribute_declaration ::=
   attribute-literal "=" identifier ";"

Member pattern

module_member-pattern ::=
   visibility_attribute? property_attribute? scope_prefix_attribute? scope_attribute? type? identifier scope

Module members

module_member ::=
   symbol_declaration
   | class_declaration

Symbol declaration

symbol_declaration ::=
   visibility? prefix? scope_attribute? identifier "=" expression ";"

visibility ::=
   "public"
   | "internal"

prefix ::=
   "const"
   | "preloaded"

scope_attribute ::=
   "symbol"
   | "static"

Class declaration

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?