AcademySoftwareFoundation / OpenShadingLanguage

Advanced shading language for production GI renderers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Grammar railroad diagram

mingodad opened this issue · comments

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"