Modified the syntax of writing real-valued literals with the DSL. Casts are not needed any more: f.ex. 1.0 is implicitly cast to AcReal. The syntax is now more consistent: reals must be explicitly written as a.b, where a and b are some integers. IMPORTANT: Previously the shorthands a. and .b were allowed, not anymore. Using those shorthands will result in a compilation error

This commit is contained in:
jpekkila
2019-10-01 21:14:33 +03:00
parent b4a6ddb074
commit a0037d1a44
4 changed files with 43 additions and 30 deletions

View File

@@ -37,8 +37,9 @@ L [a-zA-Z_]
"return" { return RETURN; } "return" { return RETURN; }
{D}+"."?{D}*[flud]? { return NUMBER; } /* Literals */ {D}+"."{D}+ { return REAL_NUMBER; } /* Literals */
"."{D}+[flud]? { return NUMBER; } {D}+"."{D}+[fd]+ { return NUMBER; }
{D}+[lu]* { return NUMBER; }
{L}({L}|{D})* { return IDENTIFIER; } {L}({L}|{D})* { return IDENTIFIER; }
\"(.)*\" { return IDENTIFIER; } /* String */ \"(.)*\" { return IDENTIFIER; } /* String */

View File

@@ -14,7 +14,7 @@ int yyget_lineno();
%} %}
%token CONSTANT IN OUT UNIFORM %token CONSTANT IN OUT UNIFORM
%token IDENTIFIER NUMBER %token IDENTIFIER NUMBER REAL_NUMBER
%token RETURN %token RETURN
%token SCALAR VECTOR MATRIX SCALARFIELD SCALARARRAY %token SCALAR VECTOR MATRIX SCALARFIELD SCALARARRAY
%token VOID INT INT3 COMPLEX %token VOID INT INT3 COMPLEX
@@ -217,7 +217,8 @@ type_specifier: VOID
identifier: IDENTIFIER { $$ = astnode_create(NODE_IDENTIFIER, NULL, NULL); astnode_set_buffer(yytext, $$); } identifier: IDENTIFIER { $$ = astnode_create(NODE_IDENTIFIER, NULL, NULL); astnode_set_buffer(yytext, $$); }
; ;
number: NUMBER { $$ = astnode_create(NODE_UNKNOWN, NULL, NULL); astnode_set_buffer(yytext, $$); } number: REAL_NUMBER { $$ = astnode_create(NODE_REAL_NUMBER, NULL, NULL); astnode_set_buffer(yytext, $$); }
| NUMBER { $$ = astnode_create(NODE_UNKNOWN, NULL, NULL); astnode_set_buffer(yytext, $$); }
; ;
return: RETURN { $$ = astnode_create(NODE_UNKNOWN, NULL, NULL); astnode_set_buffer(yytext, $$); } return: RETURN { $$ = astnode_create(NODE_UNKNOWN, NULL, NULL); astnode_set_buffer(yytext, $$); }

View File

@@ -7,14 +7,15 @@
Statements: return value Statements: return value
block block
*/ */
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h>
#define BUFFER_SIZE (4096) #define BUFFER_SIZE (4096)
#define GEN_ID(X) X #define GEN_ID(X) X
#define GEN_STR(X) #X #define GEN_STR(X) #X
// clang-format off
#define FOR_NODE_TYPES(FUNC) \ #define FOR_NODE_TYPES(FUNC) \
FUNC(NODE_UNKNOWN), \ FUNC(NODE_UNKNOWN), \
FUNC(NODE_DEFINITION), \ FUNC(NODE_DEFINITION), \
@@ -27,16 +28,18 @@
FUNC(NODE_FUNCTION_DECLARATION), \ FUNC(NODE_FUNCTION_DECLARATION), \
FUNC(NODE_COMPOUND_STATEMENT), \ FUNC(NODE_COMPOUND_STATEMENT), \
FUNC(NODE_FUNCTION_PARAMETER_DECLARATION), \ FUNC(NODE_FUNCTION_PARAMETER_DECLARATION), \
FUNC(NODE_MULTIDIM_SUBSCRIPT_EXPRESSION) FUNC(NODE_MULTIDIM_SUBSCRIPT_EXPRESSION), \
FUNC(NODE_REAL_NUMBER)
// clang-format on
/* /*
// Recreating strdup is not needed when using the GNU compiler. // Recreating strdup is not needed when using the GNU compiler.
// Let's also just say that anything but the GNU // Let's also just say that anything but the GNU
// compiler is NOT supported, since there are also // compiler is NOT supported, since there are also
// some gcc-specific calls in the files generated // some gcc-specific calls in the files generated
// by flex and being completely compiler-independent is // by flex and being completely compiler-independent is
// not a priority right now // not a priority right now
#ifndef strdup #ifndef strdup
static inline char* static inline char*
strdup(const char* in) strdup(const char* in)
{ {
@@ -53,36 +56,32 @@ strdup(const char* in)
#endif #endif
*/ */
typedef enum { typedef enum { FOR_NODE_TYPES(GEN_ID), NUM_NODE_TYPES } NodeType;
FOR_NODE_TYPES(GEN_ID),
NUM_NODE_TYPES
} NodeType;
typedef struct astnode_s { typedef struct astnode_s {
int id; int id;
struct astnode_s* lhs; struct astnode_s* lhs;
struct astnode_s* rhs; struct astnode_s* rhs;
NodeType type; // Type of the AST node NodeType type; // Type of the AST node
char* buffer; // Indentifiers and other strings (empty by default) char* buffer; // Indentifiers and other strings (empty by default)
int token; // Type of a terminal (that is not a simple char) int token; // Type of a terminal (that is not a simple char)
int prefix; // Tokens. Also makes the grammar since we don't have int prefix; // Tokens. Also makes the grammar since we don't have
int infix; // to divide it into max two-child rules int infix; // to divide it into max two-child rules
int postfix; // (which makes it much harder to read) int postfix; // (which makes it much harder to read)
} ASTNode; } ASTNode;
static inline ASTNode* static inline ASTNode*
astnode_create(const NodeType type, ASTNode* lhs, ASTNode* rhs) astnode_create(const NodeType type, ASTNode* lhs, ASTNode* rhs)
{ {
ASTNode* node = malloc(sizeof(node[0])); ASTNode* node = malloc(sizeof(node[0]));
static int id_counter = 0; static int id_counter = 0;
node->id = id_counter++; node->id = id_counter++;
node->type = type; node->type = type;
node->lhs = lhs; node->lhs = lhs;
node->rhs = rhs; node->rhs = rhs;
node->buffer = NULL; node->buffer = NULL;
node->prefix = node->infix = node->postfix = 0; node->prefix = node->infix = node->postfix = 0;
@@ -107,7 +106,6 @@ astnode_destroy(ASTNode* node)
free(node); free(node);
} }
extern ASTNode* root; extern ASTNode* root;
/* /*

View File

@@ -395,16 +395,29 @@ traverse(const ASTNode* node)
// Do a regular translation // Do a regular translation
if (translate(node->token)) if (translate(node->token))
printf("%s ", translate(node->token)); printf("%s ", translate(node->token));
if (node->buffer) if (node->buffer) {
printf("%s ", node->buffer); if (node->type == NODE_REAL_NUMBER) {
printf("%s(%s) ", translate(SCALAR),
node->buffer); // Cast to correct precision
}
else {
printf("%s ", node->buffer);
}
}
} }
} }
else { else {
// Do a regular translation // Do a regular translation
if (translate(node->token)) if (translate(node->token))
printf("%s ", translate(node->token)); printf("%s ", translate(node->token));
if (node->buffer) if (node->buffer) {
printf("%s ", node->buffer); if (node->type == NODE_REAL_NUMBER) {
printf("%s(%s) ", translate(SCALAR), node->buffer); // Cast to correct precision
}
else {
printf("%s ", node->buffer);
}
}
} }
} }