From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

Name

SPVM::Document::Language::SyntaxParsing - Syntax Parsing in the SPVM Language

Description

This document describes the grammer of the SPVM language and syntax parsing.

Syntax Parsing

Syntax parsing is the step to build an AST.

Thie step is just after tokenization.

Syntax parsing is performed according to the grammer of the SPVM language.

Grammer

The grammer of the SPVM language is described using GNU Bison syntax.

%token <opval> CLASS HAS METHOD OUR ENUM MY USE AS REQUIRE ALIAS ALLOW OUTMOST_CLASS MUTABLE
%token <opval> ATTRIBUTE MAKE_READ_ONLY INTERFACE EVAL_ERROR_ID ARGS_WIDTH VERSION_DECL
%token <opval> IF UNLESS ELSIF ELSE FOR WHILE LAST NEXT SWITCH CASE DEFAULT BREAK EVAL
%token <opval> SYMBOL_NAME VAR_NAME CONSTANT EXCEPTION_VAR
%token <opval> UNDEF VOID BYTE SHORT INT LONG FLOAT DOUBLE STRING OBJECT TRUE FALSE END_OF_FILE
%token <opval> FATCAMMA RW RO WO INIT NEW OF BASIC_TYPE_ID EXTENDS SUPER
%token <opval> RETURN WEAKEN DIE WARN PRINT SAY OUTMOST_CLASS_NAME UNWEAKEN '[' '{' '('
%type <opval> grammar
%type <opval> field_name method_name class_name
%type <opval> type qualified_type basic_type array_type opt_basic_type
%type <opval> array_type_with_length ref_type return_type type_comment opt_type_comment union_type
%type <opval> opt_classes classes class class_block opt_extends version_decl
%type <opval> opt_definitions definitions definition
%type <opval> enumeration enumeration_block opt_enumeration_items enumeration_items enumeration_item
%type <opval> method anon_method opt_args args arg use require class_alias our has anon_method_fields anon_method_field interface allow
%type <opval> opt_attributes attributes
%type <opval> opt_statements statements statement if_statement else_statement
%type <opval> for_statement while_statement foreach_statement
%type <opval> switch_statement case_statement case_statements opt_case_statements default_statement
%type <opval> block eval_block init_statement switch_block if_require_statement
%type <opval> die
%type <opval> var_decl var
%type <opval> operator opt_operators operators opt_operator
%type <opval> void_return_operator warn
%type <opval> unary_operator array_length
%type <opval> inc dec
%type <opval> binary_operator arithmetic_operator bit_operator comparison_operator string_concatenation logical_operator
%type <opval> assign
%type <opval> new array_init
%type <opval> type_check type_cast can
%type <opval> call_method
%type <opval> array_access field_access
%type <opval> weaken_field unweaken_field isweak_field
%type <opval> sequential
%right <opval> ASSIGN SPECIAL_ASSIGN
%left <opval> LOGICAL_OR
%left <opval> LOGICAL_AND
%left <opval> BIT_OR BIT_XOR
%left <opval> BIT_AND
%nonassoc <opval> NUMEQ NUMNE STREQ STRNE
%nonassoc <opval> NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA ISA_ERROR IS_TYPE IS_ERROR IS_COMPILE_TYPE NUMERIC_CMP STRING_CMP CAN
%left <opval> SHIFT
%left <opval> '+' '-' '.'
%left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG MODULO MODULO_UNSIGNED_INT MODULO_UNSIGNED_LONG
%right <opval> LOGICAL_NOT BIT_NOT '@' REFERENCE DEREFERENCE PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK TYPE_NAME COMPILE_TYPE_NAME DUMP NEW_STRING_LEN IS_READ_ONLY COPY
%nonassoc <opval> INC DEC
%left <opval> ARROW
grammar
: opt_classes
field_name
: SYMBOL_NAME
method_name
: SYMBOL_NAME
class_name
: SYMBOL_NAME
qualified_type
: type
| MUTABLE type {
type
: basic_type
| array_type
| ref_type
basic_type
: SYMBOL_NAME
| BYTE
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| OBJECT
| STRING
ref_type
: basic_type '*'
array_type
: basic_type '[' ']'
| array_type '[' ']'
array_type_with_length
: basic_type '[' operator ']'
| array_type '[' operator ']'
return_type
: qualified_type opt_type_comment
| VOID
opt_type_comment
: /* Empty */
| type_comment
type_comment
: OF union_type
union_type
: union_type BIT_OR type
| type
opt_classes
: /* Empty */
| classes
classes
: classes class
| class
class
: CLASS opt_basic_type opt_extends class_block END_OF_FILE
| CLASS opt_basic_type opt_extends ':' opt_attributes class_block END_OF_FILE
| CLASS opt_basic_type opt_extends ';' END_OF_FILE
| CLASS opt_basic_type opt_extends ':' opt_attributes ';' END_OF_FILE
opt_basic_type
: /* Empty */
| basic_type
opt_extends
: /* Empty */
| EXTENDS basic_type
class_block
: '{' opt_definitions '}'
opt_definitions
: /* Empty */
| definitions
definitions
: definitions definition
| definition
definition
: version_decl
| use
| class_alias
| allow
| interface
| init_statement
| enumeration
| our
| has ';'
| method
init_statement
: INIT block
version_decl
: VERSION_DECL CONSTANT ';'
use
: USE basic_type ';'
| USE basic_type AS class_name ';'
require
: REQUIRE basic_type
class_alias
: ALIAS basic_type AS class_name ';'
allow
: ALLOW basic_type ';'
interface
: INTERFACE basic_type ';'
enumeration
: opt_attributes ENUM enumeration_block
enumeration_block
: '{' opt_enumeration_items '}'
opt_enumeration_items
: /* Empty */
| enumeration_items
enumeration_items
: enumeration_items ',' enumeration_item
| enumeration_items ','
| enumeration_item
enumeration_item
: method_name
| method_name ASSIGN CONSTANT
our
: OUR VAR_NAME ':' opt_attributes qualified_type opt_type_comment ';'
has
: HAS field_name ':' opt_attributes qualified_type opt_type_comment
method
: opt_attributes METHOD method_name ':' return_type '(' opt_args ')' block
| opt_attributes METHOD method_name ':' return_type '(' opt_args ')' ';'
| opt_attributes METHOD ':' return_type '(' opt_args ')' block
| opt_attributes METHOD ':' return_type '(' opt_args ')' ';'
anon_method
: opt_attributes METHOD ':' return_type '(' opt_args ')' block
| '[' anon_method_fields ']' opt_attributes METHOD ':' return_type '(' opt_args ')' block
opt_args
: /* Empty */
| args
args
: args ',' arg
| args ','
| arg
arg
: var ':' qualified_type opt_type_comment
| var ':' qualified_type opt_type_comment ASSIGN operator
anon_method_fields
: anon_method_fields ',' anon_method_field
| anon_method_fields ','
| anon_method_field
anon_method_field
: HAS field_name ':' opt_attributes qualified_type opt_type_comment
| HAS field_name ':' opt_attributes qualified_type opt_type_comment ASSIGN operator
| var ':' opt_attributes qualified_type opt_type_comment
| var ':' opt_attributes qualified_type opt_type_comment ASSIGN operator
opt_attributes
: /* Empty */
| attributes
attributes
: attributes ATTRIBUTE
| ATTRIBUTE
opt_statements
: /* Empty */
| statements
statements
: statements statement
| statement
statement
: if_statement
| for_statement
| foreach_statement
| while_statement
| block
| switch_statement
| case_statement
| default_statement
| eval_block
| if_require_statement
| LAST ';'
| NEXT ';'
| BREAK ';'
| RETURN ';'
| RETURN operator ';'
| operator ';'
| void_return_operator ';'
| ';'
| die ';'
die
: DIE operator
| DIE
| DIE type operator
| DIE type
| DIE operator ',' operator
void_return_operator
: warn
| PRINT operator
| SAY operator
| weaken_field
| unweaken_field
| MAKE_READ_ONLY operator
warn
: WARN operator
| WARN
for_statement
: FOR '(' opt_operator ';' operator ';' opt_operator ')' block
foreach_statement
: FOR var_decl '(' '@' operator ')' block
| FOR var_decl '(' '@' '{' operator '}' ')' block
while_statement
: WHILE '(' operator ')' block
switch_statement
: SWITCH '(' operator ')' switch_block
switch_block
: '{' opt_case_statements '}'
| '{' opt_case_statements default_statement '}'
opt_case_statements
: /* Empty */
| case_statements
case_statements
: case_statements case_statement
| case_statement
case_statement
: CASE operator ':' block
| CASE operator ':'
default_statement
: DEFAULT ':' block
| DEFAULT ':'
if_require_statement
: IF '(' require ')' block
| IF '(' require ')' block ELSE block
if_statement
: IF '(' operator ')' block else_statement
| UNLESS '(' operator ')' block else_statement
else_statement
: /* NULL */
| ELSE block
| ELSIF '(' operator ')' block else_statement
block
: '{' opt_statements '}'
eval_block
: EVAL block
var_decl
: MY var ':' qualified_type opt_type_comment
| MY var
var
: VAR_NAME
opt_operators
: /* Empty */
| operators
opt_operator
: /* Empty */
| operator
operator
: var
| EXCEPTION_VAR
| CONSTANT
| UNDEF
| type_cast
| new
| var_decl
| EVAL_ERROR_ID
| ARGS_WIDTH
| TRUE
| FALSE
| OUTMOST_CLASS_NAME
| unary_operator
| binary_operator
| assign
| inc
| dec
| type_check
| BASIC_TYPE_ID type
| can
| array_init
| array_access
| field_access
| isweak_field
| call_method
| sequential
sequential
: '(' operators ')'
operators
: operators ',' operator
| operators ','
| operator
unary_operator
: '+' operator %prec PLUS
| '-' operator %prec MINUS
| BIT_NOT operator
| TYPE_NAME operator
| COMPILE_TYPE_NAME operator
| STRING_LENGTH operator
| DUMP operator
| DEREFERENCE var
| REFERENCE operator
| NEW_STRING_LEN operator
| COPY operator
| IS_READ_ONLY operator
| array_length
array_length
: '@' operator
| '@' '{' operator '}'
| SCALAR '@' operator
| SCALAR '@' '{' operator '}'
inc
: INC operator
| operator INC
dec
: DEC operator
| operator DEC
binary_operator
: arithmetic_operator
| bit_operator
| comparison_operator
| string_concatenation
| logical_operator
arithmetic_operator
: operator '+' operator
| operator '-' operator
| operator '*' operator
| operator DIVIDE operator
| operator DIVIDE_UNSIGNED_INT operator
| operator DIVIDE_UNSIGNED_LONG operator
| operator MODULO operator
| operator MODULO_UNSIGNED_INT operator
| operator MODULO_UNSIGNED_LONG operator
bit_operator
: operator BIT_XOR operator
| operator BIT_AND operator
| operator BIT_OR operator
| operator SHIFT operator
comparison_operator
: operator NUMEQ operator
| operator NUMNE operator
| operator NUMGT operator
| operator NUMGE operator
| operator NUMLT operator
| operator NUMLE operator
| operator NUMERIC_CMP operator
| operator STREQ operator
| operator STRNE operator
| operator STRGT operator
| operator STRGE operator
| operator STRLT operator
| operator STRLE operator
| operator STRING_CMP operator
string_concatenation
: operator '.' operator
logical_operator
: operator LOGICAL_OR operator
| operator LOGICAL_AND operator
| LOGICAL_NOT operator
type_check
: operator ISA type
| operator ISA_ERROR type
| operator IS_TYPE type
| operator IS_ERROR type
| operator IS_COMPILE_TYPE qualified_type
type_cast
: '(' qualified_type ')' operator %prec CONVERT
| operator ARROW '(' qualified_type ')' %prec CONVERT
can
: operator CAN method_name
| operator CAN CONSTANT
assign
: operator ASSIGN operator
| operator SPECIAL_ASSIGN operator
new
: NEW basic_type
| NEW array_type_with_length
| anon_method
array_init
: '[' opt_operators ']'
| '{' operators '}'
| '{' '}'
call_method
: OUTMOST_CLASS SYMBOL_NAME '(' opt_operators ')'
| OUTMOST_CLASS SYMBOL_NAME
| basic_type ARROW method_name '(' opt_operators ')'
| basic_type ARROW method_name
| operator ARROW method_name '(' opt_operators ')'
| operator ARROW method_name
| operator ARROW '(' opt_operators ')'
array_access
: operator ARROW '[' operator ']'
| array_access '[' operator ']'
| field_access '[' operator ']'
field_access
: operator ARROW '{' field_name '}'
| field_access '{' field_name '}'
| array_access '{' field_name '}'
weaken_field
: WEAKEN var ARROW '{' field_name '}'
unweaken_field
: UNWEAKEN var ARROW '{' field_name '}'
isweak_field
: ISWEAK var ARROW '{' field_name '}'

Grammer Token

These are tokens for "Grammer" in grammer.

TokensToken Values
ALIASalias
ALLOWallow
ARROW->
ASas
ASSIGN=
BIT_AND&
BASIC_TYPE_IDbasic_type_id
BIT_NOT~
BIT_OR|
BIT_XOR^
BREAKbreak
BYTEbyte
CASEcase
CLASSclass
VAR_NAMEA variable name
COMPILE_TYPE_NAMEcompile_type_name
CONSTANTA literal
CONVERT(TYPE_NAME)
COPYcopy
OUTMOST_CLASS&
OUTMOST_CLASS_NAME__PACKAGE__
DEC--
DEFAULTdefault
DEREFERENCE$
ATTRIBUTEAn attribute name
DIEdie
DIVIDE/
DIVIDE_UNSIGNED_INTdiv_uint
DIVIDE_UNSIGNED_LONGdiv_ulong
DOUBLEdouble
DUMPdump
ELSEelse
ELSIFelsif
END_OF_FILEThe end of the file
ENUMenum
EVAL_ERROR_IDeval_error_id
EXTENDSextends
EVALeval
EXCEPTION_VAR$@
FATCAMMA=>
FLOATfloat
FORfor
HAShas
CANcan
IFif
INTERFACEinterface
INC++
INITINIT
INTint
ISAisa
ISWEAKisweak
IS_TYPEis_type
IS_READ_ONLYis_read_only
LASTlast
LENGTHlength
LOGICAL_AND&&
LOGICAL_NOT!
LOGICAL_OR||
LONGlong
MAKE_READ_ONLYmake_read_only
METHODmethod
MINUS-
MUTABLEmutable
MYmy
SYMBOL_NAMEA symbol name
NEWnew
NEW_STRING_LENnew_string_len
OFof
NEXTnext
NUMEQ==
NUMERIC_CMP<=>
NUMGE>=
NUMGT>
NUMLE<=
NUMLT<
NUMNE!=
OBJECTobject
OURour
PLUS+
PRINTprint
REF\
TYPE_NAMEtype_name
MODULO%
MODULO_UNSIGNED_INTmod_uint
MODULO_UNSIGNED_LONGmod_ulong
REQUIRErequire
RETURNreturn
ROro
RWrw
SAYsay
SCALARscalar
SELFself
SHIFT<<
>>
>>>
SHORTshort
SPECIAL_ASSIGN+=
-=
*=
/=
&=
|=
^=
%=
<<=
>>=
>>>=
.=
SRING_CMPcmp
STREQeq
STRGEge
STRGTgt
STRINGstring
STRLEle
STRLTlt
STRNEne
SWITCHswitch
UNDEFundef
UNLESSunless
UNWEAKENunweaken
USEuse
VARvar
VERSIONversion
VOIDvoid
WARNwarn
WEAKENweaken
WHILEwhile
WOwo

Operator Precidence

The operator precidence in the SPVM language is described using GNU Bison syntax.

The bottom is the highest precidence and the top is the lowest precidence.

%right <opval> ASSIGN SPECIAL_ASSIGN
%left <opval> LOGICAL_OR
%left <opval> LOGICAL_AND
%left <opval> BIT_OR BIT_XOR
%left <opval> BIT_AND
%nonassoc <opval> NUMEQ NUMNE STREQ STRNE
%nonassoc <opval> NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA ISA_ERROR IS_TYPE IS_ERROR IS_COMPILE_TYPE NUMERIC_CMP STRING_CMP CAN
%left <opval> SHIFT
%left <opval> '+' '-' '.'
%left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG MODULO MODULO_UNSIGNED_INT MODULO_UNSIGNED_LONG
%right <opval> LOGICAL_NOT BIT_NOT '@' REFERENCE DEREFERENCE PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK TYPE_NAME COMPILE_TYPE_NAME DUMP NEW_STRING_LEN IS_READ_ONLY COPY
%nonassoc <opval> INC DEC
%left <opval> ARROW

The operator precidence can be increased using ().

# a * b is calculated at first
a * b + c
# b + c is calculated at first
a * (b + c)

See Also

Copyright & License

Copyright (c) 2023 Yuki Kimoto

MIT License