# Separate a .csg file into multiple colours. See https://stacks.stanford.edu/file/druid:pc102tg3656/TR011.pdf

# docs: https://github.com/openscad/openscad/wiki/CSG-File-Format (main reference)
#       https://github.com/bobc/csg_tool/blob/master/grammar/CSG.y (pretty much ignored)
#       https://mfix.netl.doe.gov/gitlab/rangarad/csg-eb/-/blob/main/src/csg/parser.cpp?ref_type=heads (suggested existence of "undef")

B<EOF> = 0;

P<begin-arguments> = "(" ;
  
P<end-arguments> = ")" ;

P<begin-array> = "[" ;

P<end-array> = "]" ;

P<begin-scope> = "{" ;
  
P<end-scope> = "}" ;

P<value-separator> = "," ;

P<object-separator> = ";" ;

P<name-separator> = "=" ;

P<array> = <begin-array> <value-list> <end-array>;

P<opt-sign> = "-",;

P<number> = <opt-sign><float>, <opt-sign><integer>;

# undef added from https://mfix.netl.doe.gov/gitlab/rangarad/csg-eb/-/blob/main/src/csg/parser.cpp?ref_type=heads
P<value> = "true", "false", "undef", <array>, <number>, <instruction>, <name>, <string> ;

P<rest-of-value-list> =  <value-separator> <value> <rest-of-value-list>,;

P<value-list> = <value> <rest-of-value-list>;

P<quote> = «\\"»;

P<escaped-char> = «\\\\.»;

P<char> = <!quote> «.»;

P<chars> = <char> <chars>,;

P<string> = <quote> <chars> <quote>;

P<name> = «[A-Za-z\\\\$][A-Za-z0-9_]*»;

P<opt-exponent> = «[Ee]» <opt-sign> <integer>,;

P<opt-integer> = <integer>,;

P<decimal-part> = «[0-9][0-9]*»;

P<float> = <opt-integer> «\\\\.» <decimal-part> <opt-exponent>;

P<integer> = «[0-9][0-9]*»;

P<instruction-list> = <instruction> <instruction-list>,;

P<opt-block> = <begin-scope> <instruction-list> <end-scope>, <object-separator>;

P<argument> = <name> <name-separator> <value>, <value>;

P<rest-of-argument-list> = <value-separator> <argument> <rest-of-argument-list>,;

P<opt-argument-list> = <argument> <rest-of-argument-list>,;

P<instruction> = <name> <begin-arguments> <opt-argument-list> <end-arguments> <opt-block>;
    
P<SS> = <instruction-list> <EOF>;

E