initial commit
commit
d8df1c019a
|
@ -0,0 +1,168 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Assignment,
|
||||||
|
BinaryExpression,
|
||||||
|
Boolean,
|
||||||
|
Comment,
|
||||||
|
Expression,
|
||||||
|
ForLoop,
|
||||||
|
Identifier,
|
||||||
|
Number,
|
||||||
|
Return,
|
||||||
|
String,
|
||||||
|
UnaryExpression
|
||||||
|
} SyntaxKind;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Negate
|
||||||
|
} UnaryOperator;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Add,
|
||||||
|
Subtract
|
||||||
|
} BinaryOperator;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
UnaryOperator unaryOperator;
|
||||||
|
BinaryOperator binaryOperator;
|
||||||
|
} Operator;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
const char *string;
|
||||||
|
uint64_t number;
|
||||||
|
} Value;
|
||||||
|
|
||||||
|
typedef struct Node
|
||||||
|
{
|
||||||
|
SyntaxKind syntaxKind;
|
||||||
|
struct Node **children;
|
||||||
|
uint32_t childCount;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
UnaryOperator unaryOperator;
|
||||||
|
BinaryOperator binaryOperator;
|
||||||
|
} operator;
|
||||||
|
Value value;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
const char* SyntaxKindString(SyntaxKind syntaxKind)
|
||||||
|
{
|
||||||
|
switch(syntaxKind)
|
||||||
|
{
|
||||||
|
case Assignment: return "Assignment";
|
||||||
|
case BinaryExpression: return "BinaryExpression";
|
||||||
|
case Identifier: return "Identifier";
|
||||||
|
case Number: return "Number";
|
||||||
|
case String: return "String";
|
||||||
|
case UnaryExpression: return "UnaryExpression";
|
||||||
|
default: return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MakeIdentifierNode(
|
||||||
|
const char *id
|
||||||
|
) {
|
||||||
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
|
node->syntaxKind = Identifier;
|
||||||
|
node->value.string = id;
|
||||||
|
node->childCount = 0;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MakeNumberNode(
|
||||||
|
const char *numberString
|
||||||
|
) {
|
||||||
|
char *ptr;
|
||||||
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
|
node->syntaxKind = Number;
|
||||||
|
node->value.number = strtoul(numberString, &ptr, 10);
|
||||||
|
node->childCount = 0;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MakeStringNode(
|
||||||
|
const char *string
|
||||||
|
) {
|
||||||
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
|
node->syntaxKind = String;
|
||||||
|
node->value.string = string;
|
||||||
|
node->childCount = 0;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MakeUnaryNode(
|
||||||
|
UnaryOperator operator,
|
||||||
|
Node *child
|
||||||
|
) {
|
||||||
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
|
node->syntaxKind = UnaryExpression;
|
||||||
|
node->operator.unaryOperator = operator;
|
||||||
|
node->children = malloc(sizeof(Node*));
|
||||||
|
node->children[0] = child;
|
||||||
|
node->childCount = 1;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MakeBinaryNode(
|
||||||
|
BinaryOperator operator,
|
||||||
|
Node *left,
|
||||||
|
Node *right
|
||||||
|
) {
|
||||||
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
|
node->syntaxKind = BinaryExpression;
|
||||||
|
node->operator.binaryOperator = operator;
|
||||||
|
node->children = malloc(sizeof(Node*) * 2);
|
||||||
|
node->children[0] = left;
|
||||||
|
node->children[1] = right;
|
||||||
|
node->childCount = 2;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintBinaryOperator(BinaryOperator expression)
|
||||||
|
{
|
||||||
|
switch (expression)
|
||||||
|
{
|
||||||
|
case Add:
|
||||||
|
printf("+");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Subtract:
|
||||||
|
printf("-");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintNode(Node *node)
|
||||||
|
{
|
||||||
|
printf("%s\n", SyntaxKindString(node->syntaxKind));
|
||||||
|
switch (node->syntaxKind)
|
||||||
|
{
|
||||||
|
case BinaryExpression:
|
||||||
|
PrintBinaryOperator(node->operator.binaryOperator);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Number:
|
||||||
|
printf("%lu\n", node->value.number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintTree(Node *node)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
PrintNode(node);
|
||||||
|
for (i = 0; i < node->childCount; i += 1)
|
||||||
|
{
|
||||||
|
PrintTree(node->children[i]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
%{
|
||||||
|
extern int yywrap() { return 1; }
|
||||||
|
%}
|
||||||
|
|
||||||
|
%%
|
||||||
|
[0-9]+ return NUMBER;
|
||||||
|
[a-zA-Z][a-zA-Z0-9]* return ID;
|
||||||
|
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING;
|
||||||
|
"+" return PLUS;
|
||||||
|
"-" return MINUS;
|
||||||
|
"*" return MULTIPLY;
|
||||||
|
"/" return DIVIDE;
|
||||||
|
"%" return MOD;
|
||||||
|
"<" return LESS_THAN;
|
||||||
|
">" return GREATER_THAN;
|
||||||
|
"=" return EQUAL;
|
||||||
|
"\"" return QUOTE;
|
||||||
|
"!" return BANG;
|
||||||
|
"|" return BAR;
|
||||||
|
"&" return AMPERSAND;
|
||||||
|
"." return POINT;
|
||||||
|
"," return COMMA;
|
||||||
|
";" return SEMICOLON;
|
||||||
|
":" return COLON;
|
||||||
|
"?" return QUESTION;
|
||||||
|
"(" return LEFT_PAREN;
|
||||||
|
")" return RIGHT_PAREN;
|
||||||
|
"[" return LEFT_BRACKET;
|
||||||
|
"]" return RIGHT_BRACKET;
|
||||||
|
"{" return LEFT_BRACE;
|
||||||
|
"}" return RIGHT_BRACE;
|
||||||
|
"//" return COMMENT;
|
||||||
|
"\n" return NEWLINE;
|
||||||
|
[ \t] ;
|
||||||
|
%%
|
|
@ -0,0 +1,91 @@
|
||||||
|
%token NUMBER
|
||||||
|
%token ID
|
||||||
|
%token STRING
|
||||||
|
%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
|
||||||
|
|
||||||
|
%left PLUS MINUS
|
||||||
|
%left BANG
|
||||||
|
%left LEFT_PAREN RIGHT_PAREN
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include "ast.h"
|
||||||
|
#define YYSTYPE struct Node*
|
||||||
|
%}
|
||||||
|
|
||||||
|
%%
|
||||||
|
Main : Expression NEWLINE
|
||||||
|
{
|
||||||
|
PrintTree($1);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimaryExpression : ID
|
||||||
|
{
|
||||||
|
$$ = MakeIdentifierNode(yytext);
|
||||||
|
}
|
||||||
|
| NUMBER
|
||||||
|
{
|
||||||
|
$$ = MakeNumberNode(yytext);
|
||||||
|
}
|
||||||
|
| STRING
|
||||||
|
{
|
||||||
|
$$ = MakeStringNode(yytext);
|
||||||
|
}
|
||||||
|
| LEFT_PAREN Expression RIGHT_PAREN
|
||||||
|
;
|
||||||
|
|
||||||
|
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
|
||||||
|
;
|
||||||
|
%%
|
||||||
|
|
||||||
|
#include "lex.yy.c"
|
||||||
|
|
||||||
|
/* yacc error handler */
|
||||||
|
void yyerror(char *s)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return yyparse();
|
||||||
|
}
|
Loading…
Reference in New Issue