// expression // : identifier // | identifier operator identifier // todo: generalize to all expressions // | LEFT_PAREN expression RIGHT_PAREN // | constructor // | literal // bool HlslGrammar::acceptExpression(TIntermTyped*& node) { // identifier HlslToken idToken; if (acceptIdentifier(idToken)) { TIntermTyped* left = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string); // operator? TOperator op; if (! acceptOperator(op)) return true; TSourceLoc loc = token.loc; // identifier if (acceptIdentifier(idToken)) { TIntermTyped* right = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string); node = intermediate.addBinaryMath(op, left, right, loc); return true; } return false; } // LEFT_PAREN expression RIGHT_PAREN if (acceptTokenClass(EHTokLeftParen)) { if (! acceptExpression(node)) { expected("expression"); return false; } if (! acceptTokenClass(EHTokRightParen)) { expected("right parenthesis"); return false; } return true; } // literal if (acceptLiteral(node)) return true; // constructor if (acceptConstructor(node)) return true; return false; }
int acceptFactor(List *lp) { return acceptNumber(lp) || acceptIdentifier(lp) || ( acceptCharacter(lp,'(') && acceptExpression(lp) && acceptCharacter(lp,')') ); }
// declaration // : SEMICOLON // : fully_specified_type SEMICOLON // | fully_specified_type identifier SEMICOLON // | fully_specified_type identifier = expression SEMICOLON // | fully_specified_type identifier function_parameters SEMICOLON // function prototype // | fully_specified_type identifier function_parameters COLON semantic compound_statement // function definition // // 'node' could get created if the declaration creates code, like an initializer // or a function body. // bool HlslGrammar::acceptDeclaration(TIntermNode*& node) { node = nullptr; // fully_specified_type TType type; if (! acceptFullySpecifiedType(type)) return false; // identifier HlslToken idToken; if (acceptIdentifier(idToken)) { // = expression TIntermTyped* expressionNode = nullptr; if (acceptTokenClass(EHTokEqual)) { if (! acceptExpression(expressionNode)) { expected("initializer"); return false; } } // SEMICOLON if (acceptTokenClass(EHTokSemicolon)) { node = parseContext.declareVariable(idToken.loc, *idToken.string, type, 0, expressionNode); return true; } // function_parameters TFunction* function = new TFunction(idToken.string, type); if (acceptFunctionParameters(*function)) { // COLON semantic acceptSemantic(); // compound_statement if (peekTokenClass(EHTokLeftBrace)) return acceptFunctionDefinition(*function, node); // SEMICOLON if (acceptTokenClass(EHTokSemicolon)) return true; return false; } } // SEMICOLON if (acceptTokenClass(EHTokSemicolon)) return true; return true; }
// COLON semantic bool HlslGrammar::acceptSemantic() { // COLON if (acceptTokenClass(EHTokColon)) { // semantic HlslToken idToken; if (! acceptIdentifier(idToken)) { expected("semantic"); return false; } } return true; }
// parameter_declaration // : fully_specified_type // | fully_specified_type identifier // bool HlslGrammar::acceptParameterDeclaration(TFunction& function) { // fully_specified_type TType* type = new TType; if (! acceptFullySpecifiedType(*type)) return false; // identifier HlslToken idToken; acceptIdentifier(idToken); TParameter param = { idToken.string, type }; function.addParameter(param); return true; }
// postfix_expression // : LEFT_PAREN expression RIGHT_PAREN // | literal // | constructor // | identifier // | function_call // | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET // | postfix_expression DOT IDENTIFIER // | postfix_expression INC_OP // | postfix_expression DEC_OP // bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) { // Not implemented as self-recursive: // The logical "right recursion" is done with an loop at the end // idToken will pick up either a variable or a function name in a function call HlslToken idToken; // LEFT_PAREN expression RIGHT_PAREN if (acceptTokenClass(EHTokLeftParen)) { if (! acceptExpression(node)) { expected("expression"); return false; } if (! acceptTokenClass(EHTokRightParen)) { expected("right parenthesis"); return false; } } else if (acceptLiteral(node)) { // literal (nothing else to do yet), go on to the } else if (acceptConstructor(node)) { // constructor (nothing else to do yet) } else if (acceptIdentifier(idToken)) { // identifier or function_call name if (! peekTokenClass(EHTokLeftParen)) { node = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string); } else if (acceptFunctionCall(idToken, node)) { // function_call (nothing else to do yet) } else { expected("function call arguments"); return false; } } do { TSourceLoc loc = token.loc; TOperator postOp = HlslOpMap::postUnary(peek()); // Consume only a valid post-unary operator, otherwise we are done. switch (postOp) { case EOpIndexDirectStruct: case EOpIndexIndirect: case EOpPostIncrement: case EOpPostDecrement: advanceToken(); break; default: return true; } // We have a valid post-unary operator, process it. switch (postOp) { case EOpIndexDirectStruct: // todo break; case EOpIndexIndirect: { TIntermTyped* indexNode = nullptr; if (! acceptExpression(indexNode) || ! peekTokenClass(EHTokRightBracket)) { expected("expression followed by ']'"); return false; } // todo: node = intermediate.addBinaryMath( } case EOpPostIncrement: case EOpPostDecrement: node = intermediate.addUnaryMath(postOp, node, loc); break; default: assert(0); break; } } while (true); }