%{ #include #include "ast.h" #include "stack.h" void yyerror(FILE *fp, char *s) { fprintf (stderr, "%s\n", s); } Stack *stack; extern char *yytext; extern int yylex (void); extern FILE *yyin; %} %define api.value.type {struct Node*} %token NUMBER %token INT %token UINT %token FLOAT %token DOUBLE %token STRING %token BOOL %token STRUCT %token RETURN %token ID %token STRING_LITERAL %token PLUS %token MINUS %token MULTIPLY %token DIVIDE %token MOD %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 } %left PLUS MINUS %left BANG %left LEFT_PAREN RIGHT_PAREN %% Program : Declarations { Node **declarations; Node *declarationSequence; uint32_t declarationCount; declarations = GetDeclarations(stack, &declarationCount); declarationSequence = MakeDeclarationSequenceNode(declarations, declarationCount); PopStackFrame(stack); PrintTree(declarationSequence, 0); } Type : INT { $$ = MakeTypeNode(Int); } | UINT { $$ = MakeTypeNode(UInt); } | FLOAT { $$ = MakeTypeNode(Float); } | DOUBLE { $$ = MakeTypeNode(Double); } | STRING { $$ = MakeTypeNode(String); } | BOOL { $$ = MakeTypeNode(Bool); } ; Identifier : ID { $$ = MakeIdentifierNode(yytext); } PrimaryExpression : Identifier | NUMBER { $$ = MakeNumberNode(yytext); } | STRING { $$ = MakeStringNode(yytext); } | LEFT_PAREN Expression RIGHT_PAREN { $$ = $2; } ; UnaryExpression : BANG Expression { $$ = MakeUnaryNode(Negate, $2); } BinaryExpression : Expression PLUS Expression { $$ = MakeBinaryNode(Add, $1, $3); } | Expression MINUS Expression { $$ = MakeBinaryNode(Subtract, $1, $3); } Expression : PrimaryExpression | UnaryExpression | BinaryExpression ; VariableDeclaration : Type Identifier { $$ = MakeDeclarationNode($1, $2); } AssignmentStatement : VariableDeclaration EQUAL Expression { $$ = MakeAssignmentNode($1, $3); } | Identifier EQUAL Expression { $$ = MakeAssignmentNode($1, $3); } ReturnStatement : RETURN Expression { $$ = MakeReturnStatementNode($2); } PartialStatement : AssignmentStatement | VariableDeclaration | ReturnStatement ; Statement : PartialStatement SEMICOLON; Statements : Statement Statements { AddStatement(stack, $1); } | { PushStackFrame(stack); } Arguments : Arguments COMMA VariableDeclaration | VariableDeclaration ; Body : LEFT_BRACE Statements RIGHT_BRACE { Node **statements; Node *statementSequence; uint32_t statementCount; statements = GetStatements(stack, &statementCount); statementSequence = MakeStatementSequenceNode(statements, statementCount); $$ = MakeStatementSequenceNode(statements, statementCount); PopStackFrame(stack); } FunctionSignature : Type Identifier LEFT_PAREN Arguments RIGHT_PAREN { $$ = MakeFunctionSignatureNode($2, $1, $4); } FunctionDeclaration : FunctionSignature Body { $$ = MakeFunctionDeclarationNode($1, $2); } VariableDeclarations : VariableDeclaration SEMICOLON VariableDeclarations { AddDeclaration(stack, $1); } | { PushStackFrame(stack); } StructDeclaration : STRUCT Identifier LEFT_BRACE VariableDeclarations RIGHT_BRACE { Node **declarations; Node *declarationSequence; uint32_t declarationCount; declarations = GetDeclarations(stack, &declarationCount); declarationSequence = MakeDeclarationSequenceNode(declarations, declarationCount); $$ = MakeStructDeclarationNode($2, declarationSequence); PopStackFrame(stack); } Declaration : StructDeclaration | FunctionDeclaration ; Declarations : Declaration Declarations { AddDeclaration(stack, $1); } | { PushStackFrame(stack); } %% int main(int argc, char *argv[]) { if (argc < 2) { printf("Please provide a file.\n"); return 1; } stack = CreateStack(); FILE *fp = fopen(argv[1], "r"); yyin = fp; yyparse(fp); fclose(fp); return 0; }