grammar Material; @lexer::members { boolean ignoreNewLine = true; } material_list : material | material_list material ; material : MATERIAL material_name material_parent? LBRACE material_body RBRACE ; material_parent : COLON IDENTIFIER ; material_name : IDENTIFIER ; material_body : material_child | material_body material_child ; material_child : define_statement | technique_statement | sampler_define | uniform_define ; define_statement : DEFINES ASSIGNMENT definements SEMICOLON? ; definements : IDENTIFIER | definements SEMICOLON IDENTIFIER ; technique_statement : TECHNIQUE LBRACE RBRACE ; sampler_define : SAMPLER IDENTIFIER LBRACE RBRACE ; uniform_define : IDENTIFIER ASSIGNMENT uniform_value ; uniform_value : ; MATERIAL : 'material'; DEFINES : 'defines'; TECHNIQUE : 'technique'; SAMPLER : 'sampler'; ASSIGNMENT: '=' ; LPAREN: '(' ; RPAREN: ')' ; LBRACE: '{' ; RBRACE: '}' ; SEMICOLON: ';' ; LBRACKET: '[' ; RBRACKET: ']' ; COMMA: ',' ; COLON: ':' ; IDENTIFIER : ('a'..'z' | 'A'..'Z' | '_') (DIGIT | 'a'..'z' | 'A'..'Z' | '_')* ; fragment DECIMAL_DIGITS: '0' | ('1'..'9' DIGIT*); fragment OCTAL_DIGITS: '0' '0'..'7'+; fragment HEX_DIGITS: '0x' (DIGIT | 'a'..'f' | 'A'..'F')+; fragment DIGIT : '0'..'9'; WS: [\t\r\n\u000C ]+ -> skip; EOL: '\n' -> skip; COMMENT: ('//' ~('\n'|'\r')* '\r'? '\n' | '/*' (.)*? '*/') -> skip ;