%code requires { #include "stack.h" } %{ #include #include "ast.h" #include "stack.h" void yyerror(FILE *fp, Stack *stack, char *s) { fprintf (stderr, "%s\n", s); } extern char *yytext; extern int yylex (void); extern FILE *yyin; extern Node *rootNode; %} %define api.value.type {struct Node*} %token VOID %token INT %token UINT %token FLOAT %token DOUBLE %token STRING %token BOOL %token STRUCT %token RETURN %token STATIC %token REFERENCE %token NUMBER %token ID %token STRING_LITERAL %token PLUS %token MINUS %token STAR %token SLASH %token PERCENT %token EQUAL %token LESS_THAN %token GREATER_THAN %token QUOTE %token BANG %token BAR %token AMPERSAND %token POINT %token COMMA %token SEMICOLON %token COLON %token QUESTION %token LEFT_PAREN %token RIGHT_PAREN %token LEFT_BRACE %token RIGHT_BRACE %token LEFT_BRACKET %token RIGHT_BRACKET %token COMMENT %token NEWLINE %parse-param { FILE* fp } { Stack *stack } %define parse.error verbose %left PLUS MINUS %left BANG %left LEFT_PAREN RIGHT_PAREN %% Program : TopLevelDeclarations { Node **declarations; Node *declarationSequence; uint32_t declarationCount; declarations = GetNodes(stack, &declarationCount); declarationSequence = MakeDeclarationSequenceNode(declarations, declarationCount); PopStackFrame(stack); rootNode = declarationSequence; } BaseType : VOID { $$ = MakePrimitiveTypeNode(Void); } | INT { $$ = MakePrimitiveTypeNode(Int); } | UINT { $$ = MakePrimitiveTypeNode(UInt); } | FLOAT { $$ = MakePrimitiveTypeNode(Float); } | DOUBLE { $$ = MakePrimitiveTypeNode(Double); } | STRING { $$ = MakePrimitiveTypeNode(String); } | BOOL { $$ = MakePrimitiveTypeNode(Bool); } | Identifier { $$ = MakeCustomTypeNode(yytext); } | REFERENCE LESS_THAN Type GREATER_THAN { $$ = MakeReferenceTypeNode($3); } ; Type : BaseType { $$ = MakeTypeNode($1); } Identifier : ID { $$ = MakeIdentifierNode(yytext); } AccessExpression : Identifier POINT AccessExpression { $$ = MakeAccessExpressionNode($1, $3); } | Identifier { $$ = $1; } PrimaryExpression : NUMBER { $$ = MakeNumberNode(yytext); } | STRING { $$ = MakeStringNode(yytext); } | LEFT_PAREN Expression RIGHT_PAREN { $$ = $2; } | FunctionCallExpression | AccessExpression ; UnaryExpression : BANG Expression { $$ = MakeUnaryNode(Negate, $2); } BinaryExpression : Expression PLUS Expression { $$ = MakeBinaryNode(Add, $1, $3); } | Expression MINUS Expression { $$ = MakeBinaryNode(Subtract, $1, $3); } | Expression STAR Expression { $$ = MakeBinaryNode(Multiply, $1, $3); } Expression : PrimaryExpression | UnaryExpression | BinaryExpression ; VariableDeclaration : Identifier COLON Type { $$ = MakeDeclarationNode($3, $1); } AssignmentStatement : VariableDeclaration EQUAL Expression { $$ = MakeAssignmentNode($1, $3); } | AccessExpression EQUAL Expression { $$ = MakeAssignmentNode($1, $3); } | Identifier EQUAL Expression { $$ = MakeAssignmentNode($1, $3); } ReturnStatement : RETURN Expression { $$ = MakeReturnStatementNode($2); } | RETURN { $$ = MakeReturnVoidStatementNode(); } FunctionCallExpression : AccessExpression LEFT_PAREN Arguments RIGHT_PAREN { Node **arguments; uint32_t argumentCount; arguments = GetNodes(stack, &argumentCount); $$ = MakeFunctionCallExpressionNode($1, MakeFunctionArgumentSequenceNode(arguments, argumentCount)); PopStackFrame(stack); } PartialStatement : FunctionCallExpression | AssignmentStatement | VariableDeclaration | ReturnStatement ; Statement : PartialStatement SEMICOLON; Statements : Statement Statements { AddNode(stack, $1); } | { PushStackFrame(stack); } Arguments : PrimaryExpression COMMA Arguments { AddNode(stack, $1); } | PrimaryExpression { PushStackFrame(stack); AddNode(stack, $1); } | { PushStackFrame(stack); } ; SignatureArguments : VariableDeclaration COMMA SignatureArguments { AddNode(stack, $1); } | VariableDeclaration { PushStackFrame(stack); AddNode(stack, $1); } | ; Body : LEFT_BRACE Statements RIGHT_BRACE { Node **statements; Node *statementSequence; uint32_t statementCount; statements = GetNodes(stack, &statementCount); statementSequence = MakeStatementSequenceNode(statements, statementCount); $$ = MakeStatementSequenceNode(statements, statementCount); PopStackFrame(stack); } FunctionSignature : Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type { Node **declarations; uint32_t declarationCount; declarations = GetNodes(stack, &declarationCount); $$ = MakeFunctionSignatureNode($1, $6, MakeFunctionSignatureArgumentsNode(declarations, declarationCount), MakeFunctionModifiersNode(NULL, 0)); PopStackFrame(stack); } | STATIC Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type { Node **declarations; uint32_t declarationCount; Node *modifier = MakeStaticNode(); declarations = GetNodes(stack, &declarationCount); $$ = MakeFunctionSignatureNode($2, $7, MakeFunctionSignatureArgumentsNode(declarations, declarationCount), MakeFunctionModifiersNode(&modifier, 1)); PopStackFrame(stack); } FunctionDeclaration : FunctionSignature Body { $$ = MakeFunctionDeclarationNode($1, $2); } StructDeclaration : STRUCT Identifier LEFT_BRACE Declarations RIGHT_BRACE { Node **declarations; Node *declarationSequence; uint32_t declarationCount; declarations = GetNodes(stack, &declarationCount); declarationSequence = MakeDeclarationSequenceNode(declarations, declarationCount); $$ = MakeStructDeclarationNode($2, declarationSequence); PopStackFrame(stack); } Declaration : FunctionDeclaration | VariableDeclaration SEMICOLON ; Declarations : Declaration Declarations { AddNode(stack, $1); } | { PushStackFrame(stack); } TopLevelDeclaration : StructDeclaration; TopLevelDeclarations : TopLevelDeclaration TopLevelDeclarations { AddNode(stack, $1); } | { PushStackFrame(stack); } %%