3.1. Syntax¶
This chapter describes how program texts are syntactically analyzed.
3.1.1. Steps of analysis¶
A program text is a sequence of unicode scalar values.
A program text is first sliced to a sequence of morphemes using longest possible matching from the start to the end.
Next the morpheme sequence is reduced to a sequence of tokens, filtering out non-token morphemes.
And then, the token sequence is parsed as
a program abstract source tree.
3.1.2. Morphemes¶
3.1.2.1. Whitespace and comments¶
Regular expression |
Morpheme category |
|---|---|
|
Whitespace |
|
Comment |
Whitespace is used to make a program text easy to read and to separate tokens from each other. Space (U+0020), LF (U+000a), and CR+LF (U+000d, U+000a) are whitespace character sequences.
Note
Horizontal tab (U+0009) is not a valid whitespace character. This design decision is intended to avoid bikeshed discussion about indentation.
The categories of morphemes (, [ and { may
differ when they are located after whitespace characters.
See the description of token types for detail.
Comments are used to describe the program text.
A number sign # (U+0023) indicates a start of a comment.
The comment continues till the end of the line,
which is before the CR or LF character or the end of the program text.
Comments are treated as whitespace characters.
stdout.print_line('foo'*2) # => foofoo
stdout.print_line( 'foo' * 2 ) # => foofoo
# Comment line
do_something # trailing comment
Whitespace characters and comments are not tokens.
3.1.2.2. Symbol tokens¶
Regular expression |
Morpheme category |
|---|---|
|
Fun symbol token |
|
Data symbol token |
A symbol token consists of a leading ascii letter (a-zA-Z) or an underscore _ (U+005f),
and a trailing sequence of zero or more ascii letters (a-zA-Z), ascii digits (0-9),
underscores _ (U+005f) and question marks ? (U+0x3f).
There are two types of symbol tokens: function symbol tokens and data symbol tokens.
A function symbol token is a symbol token which represents a function symbol. Function symbols are commonly used for names of variables which contain functions. The following are exmaples of function symbols.
any?_looptake_5
A data symbol token is a symbol token which represents a data symbol. Data symbols are commonly used for names of variables which contain ordinary values. The following are examples of data symbols.
More_lines?ArrayList_classFLAT_MAP_HASH_TABLErarely_Used
3.1.2.3. Num tokens¶
Regular expression |
Morpheme category |
|---|---|
|
Num token (base10) |
|
Num token (base2) |
|
Num token (base16) |
There are three types of num tokens: base10, base16 and base2. A base10 num token represents a num in decimal, base16 in hexadecimal, and base2 in binary.
The fractional part can be represented only by base10 num tokens.
Digits before the period . (U+002e) represents the integer portion,
and digits after the period represents the fractional portion.
Underscore characters _ (U+005f) can be placed for spacing.
These are examples of num tokens, each of which represents 42.
4242__00420x2a0b_10_1010
These are examples of num tokens with the fractional portion.
0.00.0013.141_592_653
All base10, base2 and base16 num tokens cannot be directly followed
by a character which can form a symbol.
This limitation is represented as (?![a-zA-Z0-9_?]).
Thus, for example, a code fragment 24h causes a syntax error.
Note
Without this rule, for example, 0b123 is parsed as 0b1 and 23.
It is certainly error prone.
Each num token represents a number the scale of which is the count of digits of the fractional portion, and the mantissa of which is the integer made of the digits.
3.1.2.4. String tokens¶
Regular expression |
Morpheme category |
|---|---|
|
String token (simple) |
|
String token (rich) |
There are two types of string tokens: simple and rich.
In a simple string token, any characters between the two single quotation marks ' (U+0027)
are the content of the string.
If you want to include a single quotation mark itself in the string,
put two consecutive single quotation marks.
These are examples of simple string tokens.
'Hello world''Let''s go!'(this represents"Let's go!")
In a rich string token, characters between the two double quotation marks " (U+0022)
are the content of the string.
In the token, a sequence of characters prefixed by a backslash \ (U+005c) represents
a special character, such as a line feed (\n) or a double quotation mark (\").
These are examples of rich string tokens.
"Let's go!""GET /index.html HTTP/1.1\r\nHost: host.example.org\r\n"
Here is a list of backslash notations.
Notation |
Unicode |
Description |
|---|---|---|
|
U+0000 |
Null character |
|
U+0007 |
Bell |
|
U+0008 |
Backspace |
|
U+0009 |
Horizontal tab |
|
U+000a |
Line feed |
|
U+000b |
Vertical tab |
|
U+000c |
Form feed |
|
U+000d |
Carriage return |
|
U+001b |
Escape |
|
U+0022 |
Double quotation mark |
|
U+005c |
Backslash |
|
U+xxxxxx |
Character specified by a Unicode scalar value. xxxxxx are one to six hexadecimal digits (0-9a-f), which represent an integer in the range 0 to d7ff16, or e00016 to 10ffff16, inclusive. |
Note
As specified in the regex patterns, neither a simple string token nor a rich string token can span multiple program lines. That is for simplicity of lexical analysis in external tools such as editor plugins. If you want to use a text which spans multiple lines, consider using a rich str token with backslash notation, or making a data file module.
3.1.2.5. Binding token¶
Regular expression |
Morpheme category |
|---|---|
|
Binding token |
A binding token is literally \binding.
It is used for a binding expression.
3.1.2.6. Punctuation marks and operators¶
Tokens other than described above are punctuation marks or operators.
Some morphemes, like $, are reduced to different tokens depending on
whether it is placed just after a whitespace character or not.
If the morpheme is placed after a whitespace character,
the token is represented with a prefix ws,
like ws$.
If the morpheme is not placed after a whitespace character,
the token is represented with a prefix nows, like nows$.
Other morphemes, like ==, are reduced to a single token
not depending on whether it is placed just after a whitespace character or not.
Those tokens are represented literally like ==.
The list of punctuation marks and operators:
Token |
Note |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
not-equal operator |
|
less-than operator |
|
greater-than operator |
|
|
|
greater-than-or-equal-to operator |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Let clauses |
|
Local variable references |
|
Member variable references |
|
Local variable load of a function symbol |
|
Member variable load of a function symbol |
|
Access to variables or functions |
|
Elements spreading |
|
Vectors, formal receivers, or actual receivers |
|
Vectors |
|
Closing |
|
Function expressions or function arguments |
|
Function expressions |
|
Closing |
|
Parentheses expressions, formal arguments, or actual arguments |
|
Parentheses expressions |
|
Closing |
3.1.3. Abstract source tree¶
The list describes the parsing rule of the program abstract source tree, or AST,
from the token sequence of a program text.
There are several shift/reduce conflicts in the rules, and the parser always choose to shift.
program ::=topleveltoplevel ::=emptyexpressiontoplevelseq ::=emptysubstantial_seqsubstantial_seq ::=expressionexpressionsubstantial_seqexpression'='expressionsubstantial_seqexpression ::=store_opstore_op ::=logor_oplogor_op'<-'logor_oplogor_op ::=logand_oplogand_op'||'logor_oplogand_op ::=relation_oprelation_op'&&'logand_oprelation_op ::=add_opadd_op'=='add_opadd_op'!='add_opadd_op'<'add_opadd_op'>'add_opadd_op'<='add_opadd_op'>='add_opadd_op ::=multiply_opadd_op'+'multiply_opadd_op'-'multiply_opadd_op'|'multiply_opadd_op'^'multiply_opmultiply_op ::=unary_opmultiply_op'*'unary_opmultiply_op'/'unary_opmultiply_op'//'unary_opmultiply_op'%'unary_opmultiply_op'&'unary_opmultiply_op'<<'unary_opmultiply_op'>>'unary_opunary_op ::=primary'-'unary_op'!'unary_op'~'unary_opprimary ::=numstrbindingparenvecfunlocal_loadmember_loadlocal_varrefmember_varreflocal_callmember_callnum ::= NUM str ::= STRING binding ::= BINDING paren ::= 'nows('seq')' 'ws('seq')' vec ::= 'nows['vec_body']' 'ws['vec_body']' fun ::= 'nows{'fun_body'}' 'ws{'fun_body'}' local_load ::= DATA_SYM | nows'$' FUN_SYM | ws'$' FUN_SYM local_varref ::= 'nows:' DATA_SYM 'ws:' DATA_SYM 'nows:' FUN_SYM 'ws:' FUN_SYM local_call ::= FUN_SYMrecvargsmember_load ::=primary'.' DATA_SYMprimary'nows$' FUN_SYM member_varref ::=primary'nows:' DATA_SYMprimary'nows:' FUN_SYM member_call ::=primary'.' FUN_SYMrecvargsrecv ::=empty'nows['expression']' args ::=paren_argsfun_argsparen_args ::=empty'nows('vec_body')' fun_args ::=emptyfun_argfun_argsfun_arg ::= 'nows{'fun_body'}' vec_body ::=emptyelements_producervec_bodyelements_producer ::=expression'...'expressionfun_body ::=formal_receiverformal_argsseqformal_receiver ::=empty'nows['expression']' formal_args ::=empty'nows('vec_body')' empty ::=
The following identifiers represent token types.
Token type |
Description |
|---|---|
FUN_SYM |
Function symbol token such as |
DATA_SYM |
Data symbol token such as |
NUM |
Num token such as |
STRING |
String token such as |
BINDING |
Binding token |
Those enclosed by single quotation marks |