AcademySoftwareFoundation / OpenShadingLanguage

Advanced shading language for production GI renderers
BSD 3-Clause "New" or "Revised" License
2.05k stars 347 forks source link

Grammar railroad diagram #1789

Open mingodad opened 3 months ago

mingodad commented 3 months ago

I've just added this project grammar to https://mingodad.github.io/parsertl-playground/playground/ an Yacc/Lex compatible online editor/tester (select OpenShadingLanguage parser (partially working) from Examples then click Parse to see a parse tree for the content in Input source).

Notice that I've replaced right recursion by left recursion in some rules and fixed the reduce/reduce conflicts changing some rules.

And here is an EBNF to generate a nice navigable railroad diagram:

//
// EBNF to be viewd at
//  (IPV6) https://www.bottlecaps.de/rr/ui
//  (IPV4) https://rr.red-dove.com/ui
//
// Copy and paste this at one of the urls shown above in the 'Edit Grammar' tab
// then click the 'View Diagram' tab.
//

shader_file::=
      global_declarations_opt

global_declarations_opt::=
      global_declarations
    | /*%empty*/

global_declarations::=
      global_declaration
    | global_declarations global_declaration

global_declaration::=
      shader_or_function_declaration
    | struct_declaration
    | PP_DECL

shader_or_function_declaration::=
      typespec_or_shadertype IDENTIFIER metadata_block_opt '(' formal_params_opt ')' metadata_block_opt function_body_or_just_decl

formal_params_opt::=
      formal_params
    | /*%empty*/

formal_params::=
      formal_param metadata_block_opt
    | formal_params ',' formal_param metadata_block_opt
    | formal_params ','

formal_param::=
      outputspec typespec ident_init_opt
    | outputspec typespec IDENTIFIER arrayspec initializer_list_opt

metadata_block_opt::=
      METADATA_BEGIN metadata ']' ']'
    | /*%empty*/

metadata::=
      metadatum
    | metadata ',' metadatum
    | metadata ','

metadatum::=
      simple_typename ident_initializer
    | simple_typename IDENTIFIER arrayspec initializer_list

function_body_or_just_decl::=
      '{' statement_list '}'
    | ';'

function_declaration::=
      typespec IDENTIFIER '(' formal_params_opt ')' metadata_block_opt function_body_or_just_decl

struct_declaration::=
      STRUCT IDENTIFIER '{' field_declarations '}' ';'

field_declarations::=
      field_declaration
    | field_declarations field_declaration

field_declaration::=
      typespec typed_field_list ';'

typed_field_list::=
      typed_field
    | typed_field_list ',' typed_field

typed_field::=
      IDENTIFIER
    | IDENTIFIER arrayspec

local_declaration::=
      function_declaration
    | variable_declaration

variable_declaration::=
      typespec def_expressions ';'

def_expressions::=
      def_expression
    | def_expressions ',' def_expression

def_expression::=
      ident_init_opt
    | IDENTIFIER arrayspec initializer_list_opt

ident_initializer::=
      IDENTIFIER '=' expression

ident_init_opt::=
      IDENTIFIER
    | ident_initializer
    | IDENTIFIER '=' compound_initializer

initializer_list_opt::=
      initializer_list
    | /*%empty*/

initializer_list::=
      '=' compound_initializer

compound_initializer::=
      '{' init_expression_list '}'
    | '{' '}'

init_expression_list::=
      init_expression
    | init_expression_list_rev ',' init_expression

init_expression_list_rev::=
      init_expression
    | init_expression_list_rev ',' init_expression

init_expression::=
      expression
    | compound_initializer

outputspec::=
      OUTPUT
    | /*%empty*/

simple_typename::=
      COLORTYPE
    | FLOATTYPE
    | INTTYPE
    | MATRIXTYPE
    | NORMALTYPE
    | POINTTYPE
    | STRINGTYPE
    | VECTORTYPE
    | VOIDTYPE

arrayspec::=
      '[' INT_LITERAL ']'
    | '[' ']'

typespec::=
      simple_typename
    | CLOSURE simple_typename
    | IDENTIFIER

typespec_or_shadertype::=
      simple_typename
    | CLOSURE simple_typename
    | IDENTIFIER

statement_list::=
      statement_list statement
    | /*%empty*/

statement::=
      scoped_statements
    | conditional_statement
    | loop_statement
    | loopmod_statement
    | return_statement
    | local_declaration
    | compound_expression ';'
    | ';'
    | PP_DECL

scoped_statements::=
      '{' statement_list '}'

conditional_statement::=
      IF_TOKEN '(' compound_expression ')' statement
    | IF_TOKEN '(' compound_expression ')' statement ELSE statement

loop_statement::=
      WHILE '(' compound_expression ')' statement
    | DO statement WHILE '(' compound_expression ')' ';'
    | FOR '(' for_init_statement compound_expression_opt ';' compound_expression_opt ')' statement

loopmod_statement::=
      BREAK ';'
    | CONTINUE ';'

return_statement::=
      RETURN expression_opt ';'
    | RETURN compound_initializer ';'

for_init_statement::=
      expression_opt ';'
    | variable_declaration

expression_list::=
      expression
    | expression_list ',' expression

expression_opt::=
      expression
    | /*%empty*/

compound_expression_opt::=
      compound_expression
    | /*%empty*/

compound_expression::=
      expression
    | expression ',' compound_expression

expression::=
      INT_LITERAL
    | FLOAT_LITERAL
    | string_literal_group
    | variable_ref
    | incdec_op variable_lvalue
    | binary_expression
    | unary_op expression
    | '(' compound_expression ')'
    | function_call
    | assign_expression
    | ternary_expression
    | typecast_expression
    | type_constructor

variable_lvalue::=
      id_or_field
    | id_or_field '[' expression ']'
    | id_or_field '[' expression ']' '[' expression ']'
    | id_or_field '[' expression ']' '[' expression ']' '[' expression ']'

id_or_field::=
      IDENTIFIER
    | variable_lvalue '.' IDENTIFIER

variable_ref::=
      variable_lvalue incdec_op_opt

binary_expression::=
      expression OR_OP expression
    | expression AND_OP expression
    | expression '|' expression
    | expression '^' expression
    | expression '&' expression
    | expression EQ_OP expression
    | expression NE_OP expression
    | expression '>' expression
    | expression GE_OP expression
    | expression '<' expression
    | expression LE_OP expression
    | expression SHL_OP expression
    | expression SHR_OP expression
    | expression '+' expression
    | expression '-' expression
    | expression '*' expression
    | expression '/' expression
    | expression '%' expression

unary_op::=
      '-'
    | '+'
    | '!'
    | NOT_OP
    | '~'

incdec_op_opt::=
      incdec_op
    | /*%empty*/

incdec_op::=
      INCREMENT
    | DECREMENT

type_constructor::=
      simple_typename '(' expression_list ')'

function_call::=
      IDENTIFIER '(' function_args_opt ')'

function_args_opt::=
      function_args
    | /*%empty*/

function_args::=
      expression
    | compound_initializer
    | function_args ',' expression
    | function_args ',' compound_initializer

assign_expression::=
      variable_lvalue '=' expression
    | variable_lvalue MUL_ASSIGN expression
    | variable_lvalue DIV_ASSIGN expression
    | variable_lvalue ADD_ASSIGN expression
    | variable_lvalue SUB_ASSIGN expression
    | variable_lvalue BIT_AND_ASSIGN expression
    | variable_lvalue BIT_OR_ASSIGN expression
    | variable_lvalue XOR_ASSIGN expression
    | variable_lvalue SHL_ASSIGN expression
    | variable_lvalue SHR_ASSIGN expression

ternary_expression::=
      expression '?' expression ':' expression

typecast_expression::=
      '(' simple_typename ')' expression

string_literal_group::=
      STRING_LITERAL
    | string_literal_group STRING_LITERAL

//Tokens

ADD_ASSIGN ::= "+="
SUB_ASSIGN ::= "-="
MUL_ASSIGN ::= "*="
DIV_ASSIGN ::= "/="
BIT_AND_ASSIGN ::= "&="
BIT_OR_ASSIGN ::= "|="
XOR_ASSIGN ::= "^="
SHL_ASSIGN ::= "<<="
SHR_ASSIGN ::= ">>="
SHL_OP ::= "<<"
SHR_OP ::= ">>"
AND_OP ::= "&&"
OR_OP ::= "||"
LE_OP ::= "<="
GE_OP ::= ">="
EQ_OP ::= "=="
NE_OP ::= "!="
INCREMENT ::= "++"
DECREMENT ::= "--"

/* keywords */
BREAK ::= "break"
CLOSURE ::= "closure"
COLORTYPE ::= "color"
CONTINUE ::= "continue"
DO ::= "do"
ELSE ::= "else"
FLOATTYPE ::= "float"
FOR ::= "for"
IF_TOKEN ::= "if"
INTTYPE ::= "int"
MATRIXTYPE ::= "matrix"
NORMALTYPE ::= "normal"
OUTPUT ::= "output"
POINTTYPE ::= "point"
RETURN ::= "return"
STRINGTYPE ::= "string"
STRUCT ::= "struct"
VECTORTYPE ::= "vector"
VOIDTYPE ::= "void"
WHILE ::= "while"
OR_OP ::= "or"
AND_OP ::= "and"
NOT_OP ::= "not"