alias exported symbols
This commit is contained in:
parent
f4b2d113f7
commit
9891638d1e
lommereimar
@ -1,3 +1,4 @@
|
|||||||
|
#include "calculator.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -5,145 +6,156 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "calculator.h"
|
LommereimarFileIter lommereimar_fileiter(const char* filename)
|
||||||
|
|
||||||
FileIter fileiter(const char* filename)
|
|
||||||
{
|
{
|
||||||
return (FileIter) {
|
return (LommereimarFileIter) {
|
||||||
.file = fopen(filename, "r"),
|
.file = fopen(filename, "r"),
|
||||||
.done = false,
|
.done = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
char fileiter_next(FileIter* file)
|
char lommereimar_fileiter_next(LommereimarFileIter* file)
|
||||||
{
|
{
|
||||||
if (file->done)
|
if (file->done)
|
||||||
return '\0';
|
return '\0';
|
||||||
int c = fgetc(file->file);
|
int c = fgetc(file->file);
|
||||||
if (c == EOF) {
|
if (c == EOF) {
|
||||||
file->done = true;
|
file->done = true;
|
||||||
return '\0';
|
return '\0';
|
||||||
} else {
|
} else {
|
||||||
return (char)c;
|
return (char)c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Lexer lexer(FileIter input_file)
|
LommereimarLexer lommereimar_lexer(LommereimarFileIter input_file)
|
||||||
{
|
{
|
||||||
return (Lexer) {
|
return (LommereimarLexer) {
|
||||||
.input_file = input_file,
|
.input_file = input_file,
|
||||||
.current = fileiter_next(&input_file),
|
.current = lommereimar_fileiter_next(&input_file),
|
||||||
.pos = (Position) {
|
.pos = (LommereimarPosition) {
|
||||||
.line = 1,
|
.line = 1,
|
||||||
.col = 1,
|
.col = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexer_step(Lexer* lexer)
|
void lommereimar_lexer_step(LommereimarLexer* lexer)
|
||||||
{
|
{
|
||||||
lexer->current = fileiter_next(&lexer->input_file);
|
lexer->current = lommereimar_fileiter_next(&lexer->input_file);
|
||||||
if (lexer->current) {
|
if (lexer->current) {
|
||||||
lexer->pos.line++;
|
lexer->pos.line++;
|
||||||
lexer->pos.col = 1;
|
lexer->pos.col = 1;
|
||||||
} else {
|
} else {
|
||||||
lexer->pos.col++;
|
lexer->pos.col++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Token lexer_single_token(Lexer* lexer, TokenType token_type)
|
#define lexer_step lommereimar_lexer_step
|
||||||
|
|
||||||
|
LommereimarToken lommereimar_lexer_single_token(
|
||||||
|
LommereimarLexer* lexer, LommereimarTokenType token_type
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Position pos = lexer->pos;
|
LommereimarPosition pos = lexer->pos;
|
||||||
lexer_step(lexer);
|
lommereimar_lexer_step(lexer);
|
||||||
return (Token) {
|
return (LommereimarToken) {
|
||||||
.type = TokenTypePlus,
|
.type = token_type,
|
||||||
.pos = pos,
|
.pos = pos,
|
||||||
.value = NULL,
|
.value = NULL,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Token lexer_next(Lexer* lexer)
|
#define single_token lommereimar_lexer_single_token
|
||||||
|
|
||||||
|
LommereimarToken lommereimar_lexer_next(LommereimarLexer* lexer)
|
||||||
{
|
{
|
||||||
if (isspace(lexer->current)) {
|
if (isspace(lexer->current)) {
|
||||||
while (isspace(lexer->current))
|
while (isspace(lexer->current))
|
||||||
lexer_step(lexer);
|
lommereimar_lexer_step(lexer);
|
||||||
return lexer_next(lexer);
|
return lommereimar_lexer_next(lexer);
|
||||||
} else if (isdigit(lexer->current)) {
|
} else if (isdigit(lexer->current)) {
|
||||||
Position pos = lexer->pos;
|
LommereimarPosition pos = lexer->pos;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
char value[1234] = { 0 };
|
char value[1234] = { 0 };
|
||||||
while (isdigit(lexer->current)) {
|
while (isdigit(lexer->current)) {
|
||||||
value[i] = lexer->current;
|
value[i] = lexer->current;
|
||||||
lexer_step(lexer);
|
lommereimar_lexer_step(lexer);
|
||||||
}
|
}
|
||||||
char* allocated_value = malloc(sizeof(char) * strlen(value) + 1);
|
char* allocated_value = malloc(sizeof(char) * strlen(value) + 1);
|
||||||
strcpy(allocated_value, value);
|
strcpy(allocated_value, value);
|
||||||
return (Token) {
|
return (LommereimarToken) {
|
||||||
.type = TokenTypeInt,
|
.type = LommereimarTokenTypeInt,
|
||||||
.pos = pos,
|
.pos = pos,
|
||||||
.value = allocated_value,
|
.value = allocated_value,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
switch (lexer->current) {
|
switch (lexer->current) {
|
||||||
case '+':
|
case '+':
|
||||||
return lexer_single_token(lexer, TokenTypePlus);
|
return single_token(lexer, LommereimarTokenTypePlus);
|
||||||
case '-':
|
case '-':
|
||||||
return lexer_single_token(lexer, TokenTypeMinus);
|
return single_token(lexer, LommereimarTokenTypeMinus);
|
||||||
case '*':
|
case '*':
|
||||||
return lexer_single_token(lexer, TokenTypeAsterisk);
|
return single_token(lexer, LommereimarTokenTypeAsterisk);
|
||||||
case '/':
|
case '/':
|
||||||
return lexer_single_token(lexer, TokenTypeSlash);
|
return single_token(lexer, LommereimarTokenTypeSlash);
|
||||||
case '^':
|
case '^':
|
||||||
return lexer_single_token(lexer, TokenTypeHat);
|
return single_token(lexer, LommereimarTokenTypeHat);
|
||||||
default:
|
default:
|
||||||
return lexer_single_token(lexer, TokenTypeInvalidChar);
|
return single_token(lexer, LommereimarTokenTypeInvalidChar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr* allocate_expr(Expr data)
|
LommereimarExpr* lommereimar_allocate_expr(LommereimarExpr data)
|
||||||
{
|
{
|
||||||
Expr* expr = malloc(sizeof(Expr));
|
LommereimarExpr* expr = malloc(sizeof(LommereimarExpr));
|
||||||
*expr = data;
|
*expr = data;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser parser(Lexer lexer)
|
#define allocate_expr lommereimar_allocate_expr
|
||||||
|
|
||||||
|
LommereimarParser lommereimar_parser(LommereimarLexer lexer)
|
||||||
{
|
{
|
||||||
return (Parser) {
|
return (LommereimarParser) {
|
||||||
.lexer = lexer,
|
.lexer = lexer,
|
||||||
.current = lexer_next(&lexer),
|
.current = lommereimar_lexer_next(&lexer),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void parser_step(Parser* parser)
|
void lommereimar_parser_step(LommereimarParser* parser)
|
||||||
{
|
{
|
||||||
parser->current = lexer_next(&parser->lexer);
|
parser->current = lommereimar_lexer_next(&parser->lexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr* parser_parse_expr(Parser* parser) { return parser_parse_term(parser); }
|
#define parser_step lommereimar_parser_step
|
||||||
|
|
||||||
Expr* parser_parse_term(Parser* parser)
|
LommereimarExpr* lommereimar_parser_parse_expr(LommereimarParser* parser)
|
||||||
{
|
{
|
||||||
// Grammar
|
return lommereimar_parser_parse_term(parser);
|
||||||
// term -> factor (("+"|"-") factor):*
|
}
|
||||||
Position pos = parser->current.pos;
|
|
||||||
Expr* left = parser_parse_factor(parser);
|
LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser)
|
||||||
for (;;) {
|
{
|
||||||
if (parser->current.type == TokenTypePlus) {
|
// Grammar
|
||||||
parser_step(parser);
|
// term -> factor (("+"|"-") factor):*
|
||||||
Expr* right = parser_parse_factor(parser);
|
LommereimarPosition pos = parser->current.pos;
|
||||||
left = allocate_expr((Expr) {
|
LommereimarExpr* left = lommereimar_parser_parse_factor(parser);
|
||||||
.type = ExprTypeBinary,
|
for (;;) {
|
||||||
|
if (parser->current.type == LommereimarTokenTypePlus) {
|
||||||
|
parser_step(parser);
|
||||||
|
LommereimarExpr* right = lommereimar_parser_parse_factor(parser);
|
||||||
|
left = allocate_expr((LommereimarExpr) {
|
||||||
|
.type = LommereimarExprTypeBinary,
|
||||||
.pos = pos,
|
.pos = pos,
|
||||||
.binary = (ExprBinary) {
|
.binary = (LommereimarExprBinary) {
|
||||||
.type = ExprBinaryTypeAdd,
|
.type = LommereimarExprBinaryTypeAdd,
|
||||||
.left = left,
|
.left = left,
|
||||||
.right = right,
|
.right = right,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() { return EXIT_SUCCESS; }
|
int main(void) { return EXIT_SUCCESS; }
|
||||||
|
@ -1,115 +1,113 @@
|
|||||||
#ifndef CALCULATOR_H
|
#ifndef CALCULATOR_H
|
||||||
#define CALCULATOR_H
|
#define CALCULATOR_H
|
||||||
|
|
||||||
typedef struct {
|
#include <stdbool.h>
|
||||||
FILE* file;
|
#include <stdio.h>
|
||||||
bool done;
|
|
||||||
} FileIter;
|
|
||||||
|
|
||||||
FileIter fileiter(const char* filename);
|
|
||||||
|
|
||||||
char fileiter_next(FileIter* file);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int line;
|
FILE* file;
|
||||||
int col;
|
bool done;
|
||||||
} Position;
|
} LommereimarFileIter;
|
||||||
|
|
||||||
|
LommereimarFileIter lommereimar_fileiter(const char* filename);
|
||||||
|
|
||||||
|
char lommereimar_fileiter_next(LommereimarFileIter* file);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int line;
|
||||||
|
int col;
|
||||||
|
} LommereimarPosition;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TokenTypeEof,
|
LommereimarTokenTypeEof,
|
||||||
TokenTypeInvalidChar,
|
LommereimarTokenTypeInvalidChar,
|
||||||
TokenTypeInt,
|
LommereimarTokenTypeInt,
|
||||||
TokenTypePlus,
|
LommereimarTokenTypePlus,
|
||||||
TokenTypeMinus,
|
LommereimarTokenTypeMinus,
|
||||||
TokenTypeAsterisk,
|
LommereimarTokenTypeAsterisk,
|
||||||
TokenTypeSlash,
|
LommereimarTokenTypeSlash,
|
||||||
TokenTypeHat,
|
LommereimarTokenTypeHat,
|
||||||
TokenTypeLParen,
|
LommereimarTokenTypeLParen,
|
||||||
TokenTypeRParen,
|
LommereimarTokenTypeRParen,
|
||||||
} TokenType;
|
} LommereimarTokenType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// optional
|
// optional
|
||||||
char* value;
|
char* value;
|
||||||
TokenType type;
|
LommereimarTokenType type;
|
||||||
Position pos;
|
LommereimarPosition pos;
|
||||||
} Token;
|
} LommereimarToken;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FileIter input_file;
|
LommereimarFileIter input_file;
|
||||||
char current;
|
char current;
|
||||||
Position pos;
|
LommereimarPosition pos;
|
||||||
} Lexer;
|
} LommereimarLexer;
|
||||||
|
|
||||||
Lexer lexer(FileIter input_file);
|
LommereimarLexer lommereimar_lexer(LommereimarFileIter input_file);
|
||||||
|
void lommereimar_lexer_step(LommereimarLexer* lexer);
|
||||||
void lexer_step(Lexer* lexer);
|
LommereimarToken lommereimar_lexer_single_token(
|
||||||
|
LommereimarLexer* lexer, LommereimarTokenType token_type
|
||||||
Token lexer_single_token(Lexer* lexer, TokenType token_type);
|
);
|
||||||
|
LommereimarToken lommereimar_lexer_next(LommereimarLexer* lexer);
|
||||||
Token lexer_next(Lexer* lexer);
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ExprTypeEof,
|
LommereimarExprTypeEof,
|
||||||
ExprTypeError,
|
LommereimarExprTypeError,
|
||||||
ExprTypeInt,
|
LommereimarExprTypeInt,
|
||||||
ExprTypeFloat,
|
LommereimarExprTypeFloat,
|
||||||
ExprTypeUnary,
|
LommereimarExprTypeUnary,
|
||||||
ExprTypeBinary,
|
LommereimarExprTypeBinary,
|
||||||
} ExprType;
|
} LommereimarExprType;
|
||||||
|
|
||||||
typedef struct Expr Expr;
|
typedef struct LommereimarExpr LommereimarExpr;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ExprBinaryTypeAdd,
|
LommereimarExprBinaryTypeAdd,
|
||||||
ExprBinaryTypeSubtract,
|
LommereimarExprBinaryTypeSubtract,
|
||||||
ExprBinaryTypeMultiply,
|
LommereimarExprBinaryTypeMultiply,
|
||||||
ExprBinaryTypeDivide,
|
LommereimarExprBinaryTypeDivide,
|
||||||
ExprBinaryTypeExponent,
|
LommereimarExprBinaryTypeExponent,
|
||||||
} ExprBinaryType;
|
} LommereimarExprBinaryType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ExprBinaryType type;
|
LommereimarExprBinaryType type;
|
||||||
Expr* left;
|
LommereimarExpr* left;
|
||||||
Expr* right;
|
LommereimarExpr* right;
|
||||||
} ExprBinary;
|
} LommereimarExprBinary;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ExprUnaryTypeNegate,
|
LommereimarExprUnaryTypeNegate,
|
||||||
} ExprUnaryType;
|
} LommereimarExprUnaryType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ExprUnaryType type;
|
LommereimarExprUnaryType type;
|
||||||
Expr* subject;
|
LommereimarExpr* subject;
|
||||||
} ExprUnary;
|
} LommereimarExprUnary;
|
||||||
|
|
||||||
struct Expr {
|
struct LommereimarExpr {
|
||||||
ExprType type;
|
LommereimarExprType type;
|
||||||
Position pos;
|
LommereimarPosition pos;
|
||||||
union {
|
union {
|
||||||
char* error_value;
|
char* error_value;
|
||||||
int int_value;
|
int int_value;
|
||||||
float float_value;
|
float float_value;
|
||||||
ExprUnary unary;
|
LommereimarExprUnary unary;
|
||||||
ExprBinary binary;
|
LommereimarExprBinary binary;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
Expr* allocate_expr(Expr data);
|
LommereimarExpr* lommereimar_allocate_expr(LommereimarExpr data);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Lexer lexer;
|
LommereimarLexer lexer;
|
||||||
Token current;
|
LommereimarToken current;
|
||||||
} Parser;
|
} LommereimarParser;
|
||||||
|
|
||||||
Parser parser(Lexer lexer);
|
LommereimarParser lommereimar_parser(LommereimarLexer lexer);
|
||||||
|
void lommereimar_parser_step(LommereimarParser* parser);
|
||||||
void parser_step(Parser* parser);
|
LommereimarExpr* lommereimar_parser_parse_expr(LommereimarParser* parser);
|
||||||
|
LommereimarExpr* lommereimar_parser_parse_term(LommereimarParser* parser);
|
||||||
Expr* parser_parse_expr(Parser* parser);
|
LommereimarExpr* lommereimar_parser_parse_factor(LommereimarParser* parser);
|
||||||
|
|
||||||
Expr* parser_parse_term(Parser* parser);
|
|
||||||
|
|
||||||
Expr* parser_parse_factor(Parser* parser);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user