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