%token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN %token XOR_ASSIGN OR_ASSIGN TYPE_NAME %token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE RESTRICT %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID %token BOOL COMPLEX IMAGINARY %token STRUCT UNION ENUM ELLIPSIS %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN %union { char str[4096]; } %start translation_unit %{ #include <string.h> #include <stdio.h> #include <stdlib.h> // enable debug prints for this file #ifdef DEBUG #define DEBUG_PRINT(args...) printf(args) #else #define DEBUG_PRINT(args...) #endif // get tail of a string #define TAIL(str) (&str[strlen(str)]) // fifo to store expression strings #define STMT_SIZE 1024 #define FIFO_SIZE 200 typedef enum { decl_all, decl_param, decl_func, fifo_entry_num /* reflects the number of enum entries */ } fifo_entry_t; typedef struct { char fifo[FIFO_SIZE][STMT_SIZE]; unsigned int read; unsigned int write; } fifo_t; static fifo_t s_fifos[fifo_entry_num]; void yyerror(char const *s); // push an entry (typically a declaration into the fifo void fifo_push(fifo_entry_t type, const char *psz); // pop one entry from the specific category char *fifo_pop(fifo_entry_t type); char *lifo_pop(fifo_entry_t type); // tag all from category "all" to new type // this way we can collect new stuff in all and push // it to the correct section when we know more about // our context void fifo_tag(fifo_entry_t type); // check if fifo is empty int fifo_empty(fifo_entry_t type); // check fill status of queue int fifo_size(fifo_entry_t type); // map c datatype to iec (standard and userdefined) char *maptype(char *ctype); // get identifier from payload data // when used e.g. with the declarator of a struct, // the name is reproducable char *genIdentifier(char *szData); // convert input string to upper case char *strUpper(char *szStr); // check if string a starts with string b int strStartsWith(const char *a, const char *b); // terminate string after identifier boundary char *strIdentifier(char *szStr); // add symbol name to symbol table #define SYM_SIZE 128 #define SYM_COUNT 1024 int s_iSymTabCount = 0; char s_szSymTab[SYM_COUNT][SYM_SIZE]; void addSym(char *szSym); int isSym(char *szSym); // define function name of current context static char s_szFuncName[SYM_SIZE]; void setFunctionName(char *szName); char *getFunctionName(void); // lex/yacc functions extern int yylex (void); %} %% primary_expression : IDENTIFIER | CONSTANT | STRING_LITERAL | '(' expression ')' { sprintf($<str>$, "( %s )",$<str>2); } ; postfix_expression : primary_expression { sprintf($<str>$, "%s",$<str>1); } | postfix_expression '[' expression ']' { sprintf($<str>$, "%s[%s]",$<str>1, $<str>3); } | postfix_expression '(' ')' { sprintf($<str>$, "%s()",$<str>1); } | postfix_expression '(' argument_expression_list ')' { sprintf($<str>$, "%s(%s)",$<str>1, $<str>3); } | postfix_expression '.' IDENTIFIER { sprintf($<str>$, "%s.%s",$<str>1,$<str>3); } | postfix_expression PTR_OP IDENTIFIER { sprintf($<str>$, "%s %s %s",$<str>1, $<str>2, $<str>3);} | postfix_expression INC_OP { sprintf($<str>$, "%s:=%s+1",$<str>1, $<str>1); } | postfix_expression DEC_OP { sprintf($<str>$, "%s:=%s-1",$<str>1, $<str>1); } | '(' type_name ')' '{' initializer_list '}' | '(' type_name ')' '{' initializer_list ',' '}' ; argument_expression_list : assignment_expression | argument_expression_list ',' assignment_expression { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); } ; unary_expression : postfix_expression | INC_OP unary_expression { sprintf($<str>$, "(%s:=%s+1)",$<str>2, $<str>2); } | DEC_OP unary_expression { sprintf($<str>$, "(%s:=%s-1)",$<str>2, $<str>2); } | unary_operator cast_expression { if (!strcmp($<str>1, "*")) { sprintf($<str>$, "%s^",$<str>2); } else { sprintf($<str>$, "%s%s",$<str>1, $<str>2); } } | SIZEOF unary_expression { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } | SIZEOF '(' type_name ')' { sprintf($<str>$, "%s (%s)",$<str>1, $<str>3); } ; unary_operator : '&' | '*' | '+' | '-' | '~' | '!' ; cast_expression : unary_expression | '(' type_name ')' cast_expression { sprintf($<str>$, "ANY_TO_%s(%s)",$<str>2, $<str>4); } ; multiplicative_expression : cast_expression | multiplicative_expression '*' cast_expression { sprintf($<str>$, "%s * %s",$<str>1, $<str>3); } | multiplicative_expression '/' cast_expression { sprintf($<str>$, "%s / %s",$<str>1, $<str>3); } | multiplicative_expression '%' cast_expression { sprintf($<str>$, "%s %s",$<str>1, $<str>3); } ; additive_expression : multiplicative_expression | additive_expression '+' multiplicative_expression { sprintf($<str>$, "%s + %s",$<str>1, $<str>3); } | additive_expression '-' multiplicative_expression { sprintf($<str>$, "%s - %s",$<str>1, $<str>3); } ; shift_expression : additive_expression | shift_expression LEFT_OP additive_expression { sprintf($<str>$, "SHL(%s, %s)",$<str>1, $<str>3); } | shift_expression RIGHT_OP additive_expression { sprintf($<str>$, "SHR(%s, %s)",$<str>1, $<str>3); } ; relational_expression : shift_expression | relational_expression '<' shift_expression { sprintf($<str>$, "%s < %s",$<str>1, $<str>3); } | relational_expression '>' shift_expression { sprintf($<str>$, "%s > %s",$<str>1, $<str>3); } | relational_expression LE_OP shift_expression { sprintf($<str>$, "%s <= %s",$<str>1, $<str>3); } | relational_expression GE_OP shift_expression { sprintf($<str>$, "%s >= %s",$<str>1, $<str>3); } ; equality_expression : relational_expression | equality_expression EQ_OP relational_expression { sprintf($<str>$, "%s = %s",$<str>1, $<str>3); } | equality_expression NE_OP relational_expression { sprintf($<str>$, "%s <> %s",$<str>1, $<str>3); } ; and_expression : equality_expression | and_expression '&' equality_expression { sprintf($<str>$, "%s AND %s",$<str>1, $<str>3); } ; exclusive_or_expression : and_expression | exclusive_or_expression '^' and_expression { sprintf($<str>$, "%s XOR %s",$<str>1, $<str>3); } ; inclusive_or_expression : exclusive_or_expression | inclusive_or_expression '|' exclusive_or_expression { sprintf($<str>$, "%s OR %s",$<str>1, $<str>3); } ; logical_and_expression : inclusive_or_expression | logical_and_expression AND_OP inclusive_or_expression { sprintf($<str>$, "%s AND %s",$<str>1, $<str>3); } ; logical_or_expression : logical_and_expression | logical_or_expression OR_OP logical_and_expression { sprintf($<str>$, "%s OR %s",$<str>1, $<str>3); } ; conditional_expression : logical_or_expression | logical_or_expression '?' expression ':' conditional_expression ; assignment_expression : conditional_expression | unary_expression assignment_operator assignment_expression { sprintf($<str>$, "%s %s %s",$<str>1, $<str>2, $<str>3); } ; assignment_operator : '=' { sprintf($<str>$, ":="); } | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | ADD_ASSIGN | SUB_ASSIGN | LEFT_ASSIGN | RIGHT_ASSIGN | AND_ASSIGN | XOR_ASSIGN | OR_ASSIGN ; expression : assignment_expression | expression ',' assignment_expression ; constant_expression : conditional_expression ; declaration : declaration_specifiers ';' { sprintf($<str>$, "%s %s;\n",$<str>1, $<str>2); } | TYPEDEF declaration_specifiers init_declarator_list ';' { char *p; while( (p=fifo_pop(decl_func)) != NULL) /* noop */; while( (p=fifo_pop(decl_all)) != NULL) /* noop */; if (strlen($<str>3) > 0) { printf("TYPE "); printf($<str>3, $<str>2); addSym(strIdentifier($<str>3)); printf("END_TYPE\n\n"); } else { addSym($<str>4); } strcpy($<str>$, ""); } | declaration_specifiers init_declarator_list ';' { char *p; int isFuncDecl = 0; while( (p=fifo_pop(decl_func)) != NULL) { printf(p, $<str>1); isFuncDecl = 1; } if (!fifo_empty(decl_param)) { printf("\nVAR_IN_OUT\n"); while( (p=fifo_pop(decl_param)) != NULL) { printf(p, $<str>1); // isFuncDecl = 0; } printf("\nEND_VAR\n"); } if (!fifo_empty(decl_all)) { printf("\nVAR\n"); while( (p=fifo_pop(decl_all)) != NULL) { if (!strStartsWith(p, getFunctionName())) { printf(p, $<str>1); isFuncDecl = 0; } } printf("\nEND_VAR\n"); } strcpy($<str>$, ""); if (isFuncDecl) printf("\nEND_FUNCTION\n\n"); } ; declaration_specifiers : storage_class_specifier | storage_class_specifier declaration_specifiers { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } | type_specifier { sprintf($<str>$, "%s",maptype($<str>1)); } | type_specifier declaration_specifiers { sprintf($<str>$, "%s %s",$<str>1, $<str>2); sprintf($<str>$, "%s",maptype($<str>$)); } | type_qualifier | type_qualifier declaration_specifiers { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } | function_specifier | function_specifier declaration_specifiers { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } ; init_declarator_list : init_declarator | init_declarator_list ',' init_declarator { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); } ; init_declarator : declarator | declarator '=' initializer { sprintf($<str>$, "%s = %s",$<str>1, $<str>3); } ; storage_class_specifier : TYPEDEF | EXTERN | STATIC { strcpy($<str>$, ""); } | AUTO | REGISTER ; type_specifier : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX | IMAGINARY | struct_or_union_specifier | enum_specifier | TYPE_NAME ; struct_or_union_specifier : struct_or_union IDENTIFIER '{' struct_declaration_list '}' { printf("TYPE %s:\n%s\n %s\nEND_STRUCT\nEND_TYPE\n\n", $<str>2, strUpper($<str>1), $<str>4); strcpy($<str>$, $<str>2); } | struct_or_union '{' struct_declaration_list '}' { char *szTypeName = genIdentifier($<str>3); printf("TYPE %s:\n%s\n %s\nEND_STRUCT\nEND_TYPE\n\n", szTypeName, strUpper($<str>1), $<str>3); strcpy($<str>$, szTypeName); } | struct_or_union IDENTIFIER ; unnamed_struct_or_union_specifier : struct_or_union '{' struct_declaration_list '}' { strcpy($<str>$, $<str>3); } ; struct_or_union : STRUCT | UNION ; struct_declaration_list : struct_declaration { sprintf($<str>$, "%s",maptype($<str>1)); } | struct_declaration_list struct_declaration { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } ; struct_declaration : specifier_qualifier_list struct_declarator_list ';' { char *p; while( (p=fifo_pop(decl_all)) != NULL) { strcpy($<str>$, ""); sprintf(TAIL($<str>$), p, $<str>1); } } | unnamed_struct_or_union_specifier ';' ; // as a lexxer hack, I added a special case for typedefs // to the declaration rule //specifier_qualifier_list // : TYPEDEF type_specifier specifier_qualifier_list // { sprintf($<str>$, "lexxer hack - typedef found\n"); } specifier_qualifier_list : type_specifier specifier_qualifier_list { sprintf($<str>$, "%s %s", $<str>1, $<str>2); sprintf($<str>$, "%s",maptype($<str>$)); } | type_specifier { strcpy($<str>$, maptype($<str>1)); } | type_qualifier specifier_qualifier_list { sprintf($<str>$, "%s %s",$<str>1, $<str>2); sprintf($<str>$, "%s",maptype($<str>$)); } | type_qualifier ; struct_declarator_list : struct_declarator | struct_declarator_list ',' struct_declarator { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); } ; struct_declarator : declarator | ':' constant_expression | declarator ':' constant_expression ; enum_specifier : ENUM '{' enumerator_list '}' | ENUM IDENTIFIER '{' enumerator_list '}' | ENUM '{' enumerator_list ',' '}' | ENUM IDENTIFIER '{' enumerator_list ',' '}' | ENUM IDENTIFIER ; enumerator_list : enumerator | enumerator_list ',' enumerator ; enumerator : IDENTIFIER | IDENTIFIER '=' constant_expression ; type_qualifier : CONST { strcpy($<str>$, ""); } | RESTRICT { strcpy($<str>$, ""); } | VOLATILE { strcpy($<str>$, ""); } ; function_specifier : INLINE ; declarator : pointer direct_declarator { sprintf($<str>$, "%s: POINTER TO %%s;\n",$<str>2); fifo_push(decl_all, $<str>$); } | direct_declarator { if (strlen($<str>1) > 0) { sprintf($<str>$, "%s: %%s;\n",$<str>1); fifo_push(decl_all, $<str>$); } } ; declarator_funcdef : pointer direct_declarator { sprintf($<str>$, "%s: POINTER TO %%s;\n",$<str>2); // don't push function declarations to decl_all if (fifo_empty(decl_func)) { fifo_push(decl_all, $<str>$); } } | direct_declarator { if (strlen($<str>1) > 0) { sprintf($<str>$, "%s: %%s;\n",$<str>1); // don't push function declarations to decl_all if (fifo_empty(decl_func)) { fifo_push(decl_all, $<str>$); } } } ; direct_declarator : IDENTIFIER | '(' declarator ')' { //printf ("not supported direct_declerator 1 (%s)\n", $<str>2); exit(-1); strcpy($<str>$, ""); } | direct_declarator '[' type_qualifier_list assignment_expression ']' { printf ("not supported direct_declerator 2 (%s - %s)\n", $<str>3, $<str>4); exit(-1); } | direct_declarator '[' type_qualifier_list ']' { printf ("not supported direct_declerator 3 (%s)\n", $<str>3); exit(-1); } | direct_declarator '[' assignment_expression ']' { if (strlen($<str>1) > 0) { sprintf($<str>$, "%s: ARRAY[0..(%s-1)] OF %%s;\n",$<str>1, $<str>3); } else { char *p; p = lifo_pop(decl_all); sprintf($<str>1, ",0..(%s-1)] OF %%s;\n",$<str>3); strcpy($<str>$, p); strcpy(strchr($<str>$, ']'), $<str>1); } fifo_push(decl_all, $<str>$); strcpy($<str>$, ""); } | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']' | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']' | direct_declarator '[' type_qualifier_list '*' ']' | direct_declarator '[' '*' ']' | direct_declarator '[' ']' | direct_declarator '(' parameter_type_list ')' { sprintf($<str>$, "FUNCTION %s:%%s;\n",$<str>1); fifo_push(decl_func, $<str>$); setFunctionName($<str>1); strcpy($<str>$, $<str>1); // strcpy($<str>$, ""); } | direct_declarator '(' identifier_list ')' { sprintf($<str>$, "FUNCTION %s:%%s;\n",$<str>1); fifo_push(decl_func, $<str>$); setFunctionName($<str>1); strcpy($<str>$, $<str>1); // strcpy($<str>$, ""); } | direct_declarator '(' ')' { sprintf($<str>$, "FUNCTION %s:%%s;\n",$<str>1); fifo_push(decl_func, $<str>$); setFunctionName($<str>1); strcpy($<str>$, ""); // strcpy($<str>$, ""); } ; pointer : '*' | '*' type_qualifier_list | '*' pointer | '*' type_qualifier_list pointer ; type_qualifier_list : type_qualifier | type_qualifier_list type_qualifier ; parameter_type_list : parameter_list | parameter_list ',' ELLIPSIS ; parameter_list : parameter_declaration | parameter_list ',' parameter_declaration ; parameter_declaration : declaration_specifiers declarator { char *p; while (p = fifo_pop(decl_all)) { // printf(";;; %s :: %s\n\n", $<str>1, p); sprintf($<str>$, p, $<str>1); fifo_push(decl_param, $<str>$); } } | declaration_specifiers abstract_declarator | declaration_specifiers ; identifier_list : IDENTIFIER | identifier_list ',' IDENTIFIER ; type_name : specifier_qualifier_list | specifier_qualifier_list abstract_declarator ; abstract_declarator : pointer | direct_abstract_declarator | pointer direct_abstract_declarator ; direct_abstract_declarator : '(' abstract_declarator ')' | '[' ']' | '[' assignment_expression ']' | direct_abstract_declarator '[' ']' | direct_abstract_declarator '[' assignment_expression ']' | '[' '*' ']' | direct_abstract_declarator '[' '*' ']' | '(' ')' | '(' parameter_type_list ')' | direct_abstract_declarator '(' ')' | direct_abstract_declarator '(' parameter_type_list ')' ; initializer : assignment_expression | '{' initializer_list '}' | '{' initializer_list ',' '}' ; initializer_list : initializer | designation initializer | initializer_list ',' initializer | initializer_list ',' designation initializer ; designation : designator_list '=' ; designator_list : designator | designator_list designator ; designator : '[' constant_expression ']' | '.' IDENTIFIER ; statement : labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement ; labeled_statement : IDENTIFIER ':' statement | CASE constant_expression ':' statement { sprintf($<str>$, "%s:\n %s",$<str>2, $<str>4); } | DEFAULT ':' statement { sprintf($<str>$, "\nELSE:\n %s",$<str>3); } ; compound_statement : '{' '}' | '{' block_item_list '}' { sprintf($<str>$, "%s",$<str>2); } ; block_item_list : block_item | block_item_list block_item { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } ; block_item : declaration | statement //{ printf("%s\n",$<str>1); } ; expression_statement : ';' | expression ';' { sprintf($<str>$, "%s;\n",$<str>1); } ; selection_statement : IF '(' expression ')' statement { sprintf($<str>$, "\nIF %s\n%s\nEND_IF\n",$<str>3, $<str>5); } | IF '(' expression ')' statement ELSE statement { sprintf($<str>$, "\nIF %s\n%s\nELSE\n%s\nEND_IF\n",$<str>3, $<str>5, $<str>7); } | SWITCH '(' expression ')' statement { sprintf($<str>$, "(*switch*)WHILE TRUE DO\nCASE %s OF\n %s\nEND_CASE\n\n(*switch*)EXIT;\n(*switch*)END_WHILE",$<str>3, $<str>5); } ; iteration_statement : WHILE '(' expression ')' statement { sprintf($<str>$, "WHILE %s DO\n%s\nEND_WHILE\n",$<str>3, $<str>5); } | DO statement WHILE '(' expression ')' ';' { sprintf($<str>$, "IF %s\n%s\nEND_IF\nWHILE %s DO\n%s\nEND_WHILE\n",$<str>5, $<str>2, $<str>5, $<str>2); } | FOR '(' expression_statement expression_statement ')' statement | FOR '(' expression_statement expression_statement expression ')' statement { sprintf($<str>$, "%s\nWHILE %s DO\n%s\n%s;\nEND_WHILE\n",$<str>3, $<str>4, $<str>7, $<str>5); } | FOR '(' declaration expression_statement ')' statement | FOR '(' declaration expression_statement expression ')' statement ; jump_statement : GOTO IDENTIFIER ';' { sprintf($<str>$, " %s %s;\n",$<str>1, $<str>2); } | CONTINUE ';' { sprintf($<str>$, " %s;\n",$<str>1); } | BREAK ';' { sprintf($<str>$, "EXIT;\n"); } | RETURN ';' { sprintf($<str>$, " RETURN;\n"); } | RETURN expression ';' { sprintf($<str>$, " %s := (%s);\n", getFunctionName(), $<str>2); sprintf(TAIL($<str>$), " RETURN;\n"); } ; translation_unit : external_declaration | translation_unit external_declaration ; external_declaration : function_definition | declaration ; function_definition : declaration_specifiers declarator_funcdef declaration_list compound_statement { printf ("not supported function_definition\n"); exit(-1); } | declaration_specifiers declarator_funcdef compound_statement { char *p; while( (p=fifo_pop(decl_func)) != NULL) { printf(p, $<str>1); } while( (p=fifo_pop(decl_param)) != NULL) { printf(p, $<str>1); } while( (p=fifo_pop(decl_all)) != NULL) { printf(p, $<str>1); } printf("%s", $<str>3); printf("\nEND_FUNCTION\n"); strcpy($<str>$, ""); } ; declaration_list : declaration | declaration_list declaration { sprintf($<str>$, "%s %s\n",$<str>1, $<str>2); } ; %% #include <stdio.h> extern char yytext[]; extern int column; void yyerror(char const *s) { fflush(stdout); printf("\n%*s\n%*s\n", column, "^", column, s); } int main(void) { yyparse(); return 0; } /* fifo implementation */ void fifo_push(fifo_entry_t type, const char *psz) { unsigned int fifow_next = (s_fifos[type].write + 1) % FIFO_SIZE; if (fifow_next != s_fifos[type].read) { //s_fifo[s_fifow] = psz; strcpy(s_fifos[type].fifo[s_fifos[type].write], psz); s_fifos[type].write = fifow_next; } } char *lifo_pop(fifo_entry_t type) { if (s_fifos[type].read != s_fifos[type].write) { s_fifos[type].write = (s_fifos[type].write + FIFO_SIZE - 1) % FIFO_SIZE; return s_fifos[type].fifo[s_fifos[type].write]; } return NULL; } char *fifo_pop(fifo_entry_t type) { unsigned int fifor_prev; if (s_fifos[type].read != s_fifos[type].write) { fifor_prev = s_fifos[type].read; s_fifos[type].read = (s_fifos[type].read + 1) % FIFO_SIZE; return s_fifos[type].fifo[fifor_prev]; } return NULL; } int fifo_empty(fifo_entry_t type) { if (s_fifos[type].read == s_fifos[type].write) { return 1; } return 0; } int fifo_size(fifo_entry_t type) { return ((s_fifos[type].write + FIFO_SIZE) - s_fifos[type].read) % FIFO_SIZE; } void fifo_tag(fifo_entry_t type) { char *p; while ((p = fifo_pop(decl_all)) != NULL) fifo_push(type, p); } char *maptype(char *ctype) { if (!strcmp(ctype, "void")) return "BOOL"; if (!strcmp(ctype, "char") || !strcmp(ctype, "signed BYTE")) return "BYTE"; if (!strcmp(ctype, "short") || !strcmp(ctype, "signed INT")) return "INT"; if (!strcmp(ctype, "int") || !strcmp(ctype, "signed DINT")) return "DINT"; if (!strcmp(ctype, "long") || !strcmp(ctype, "signed DINT")) return "DINT"; if (!strcmp(ctype, "long DINT")) return "LINT"; if (!strcmp(ctype, "unsigned BYTE")) return "UBYTE"; if (!strcmp(ctype, "unsigned INT")) return "UINT"; if (!strcmp(ctype, "unsigned DINT")) return "UDINT"; if (!strcmp(ctype, "unsigned DINT")) return "UDINT"; if (!strcmp(ctype, "unsigned LINT")) return "ULINT"; if (!strcmp(ctype, "struct")) return "STRUCT"; if (!strcmp(ctype, "")) return ""; // printf("maptype: not found: %s\n", ctype); return ctype; } unsigned int genCRC(char *szData) { char *p; unsigned int i; unsigned int v; unsigned int crc; i = 0; crc = 42; // start value p = szData; while (*p != 0) { v = crc & 0xf8000000; crc = crc << 5; crc = crc ^ (v >> 27); crc ^= i; i++; p++; } return crc; } char *genIdentifier(char *szData) { static char szId[8]; unsigned int crc; crc = genCRC(szData); sprintf(szId, "Id%u", crc); return szId; } char *strUpper(char *szStr) { char *p; p = szStr; while (*p != 0) { if (*p >= 'a' && *p <= 'z') *p = *p - ('a' - 'A'); p++; } return szStr; } int strStartsWith(const char *a, const char *b) { if (strlen(b) > 0 && strncmp(a, b, strlen(b)) == 0) return 1; return 0; } char *strIdentifier(char *szStr) { char *p; p = szStr; while (*p != 0) { if ( (*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || (*p == '_') ) { p++; } else { *p = '\0'; return szStr; } } return szStr; } void addSym(char *szSym) { int i; if (s_iSymTabCount >= SYM_COUNT) { DEBUG_PRINT("error: symbol table size exceeded!\n"); exit(-1); } if (strlen(szSym) >= SYM_SIZE) { DEBUG_PRINT("error: symbol name too long '%s'!\n", szSym); exit(-1); } i = s_iSymTabCount++; DEBUG_PRINT("symbol: adding '%s' (%i)\n", szSym, i); strcpy(s_szSymTab[i], szSym); } int isSym(char *szSym) { int i; for (i=0; i < s_iSymTabCount; i++) { DEBUG_PRINT("symbol: check %d: %s\n", i, s_szSymTab[i]); if (!strcmp(s_szSymTab[i], szSym)) { DEBUG_PRINT("symbol: found '%s'\n", szSym); return 1; } } DEBUG_PRINT("symbol: missed '%s'\n", szSym); return 0; } void setFunctionName(char *szName) { strcpy(s_szFuncName, szName); } char *getFunctionName(void) { return s_szFuncName; }