I've checked other similar posts but I think I just need a second set of eyes. This file is for the lex Unix utility.
I created a makefile and this is the error I receive:
gcc -g -c lex.yy.c
cxref.l:57: error: expected ‘;’, ‘,’ or ‘)’ before numeric constant
make: *** [lex.yy.o] Error 1
Line 57 is just inside the void inserID() function near the top.
Here is the code:
%{
#include <stdio.h>
#include <string.h>
char identifier[1000][82];
char linesFound[100][100];
void insertId(char*, int);
int i = 0;
int lineNum = 1;
%}
%x comment
%s str
%%
"/*" BEGIN(comment);
<comment>[^*\n]* /* eat anything that's not a '*' */
<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
<comment>\n ++lineNum;
<comment>"*"+"/" BEGIN(INITIAL);
"\n" ++lineNum;
auto ;
break ;
case ;
char ;
continue ;
default ;
do ;
double ;
else ;
extern ;
float ;
for ;
goto ;
if ;
int ;
long ;
register ;
return ;
short ;
sizeof ;
static ;
struct ;
switch ;
typedef ;
union ;
unsigned ;
void ;
while ;
[*]?[a-zA-Z][a-zA-Z0-9_]* insertId(yytext, lineNum);
[^a-zA-Z0-9_]+ ;
[0-9]+ ;
%%
void insertId(char* str, int nLine)
{
char num[2];
sprintf ( num, "%d", nLine);
int iter;
for(iter = 0; iter <= i; iter++)
{
if ( strcmp(identifier[iter], str) == 0 )
{
strcat( linesFound[iter], ", " );
strcat( linesFound[iter], num );
return;
}
}
strcpy( identifier[i], str );
strcat( identifier[i], ": " );
strcpy( linesFound[i], num );
i++;
}
Your problem is:
%s str
There is a reason that it's normal to write condition names in CAPS: it makes them look like macros, which is exactly what they are.
So
void insertId(char* str, int nLine)
get macro expanded to something like:
void insertId(char* 2, int nLine)
and the compiler complains that 2 is not really expected at that point in the declaration.
Related
I have tried to figure out why the program doesn't work. It turns lowercase to uppercase, let's say I type "k", it returns K. Then I continue typint "A", it doesn't return "a", but exits. But why? Here's the code:
#include <stdio.h>
#include <stdlib.h>
int main(){
char UPPER,LOWER;
printf("Enter UPPERCASE\n");
UPPER = getchar();
if (UPPER >= 65 && UPPER <= 90)
{
UPPER = UPPER + 32;
printf("The UPPERCASE now is %c\n", UPPER);
}
printf("Enter lowercase\n");
LOWER = getchar();
if (LOWER >= 97 && LOWER <= 122)
{
LOWER = LOWER - 32;
printf("The lowercase now is %c\n", LOWER);
}
getchar();
getchar();
}
If you compile and run this code:
void main(void)
{
char c = getchar();
printf("c = %d %c\n", c, c);
c = getchar();
printf("c = %d %c\n", c, c);
}
You will see this output:
user#host ~/work/tmp $ ./test
a
c = 97 a
c = 10
/* new line there*/
This code is not the same, but works:
#include <stdlib.h>
#include <stdio.h>
#define BUFSIZE 4
int main(void)
{
char UPPER[BUFSIZE] = {0}, LOWER[BUFSIZE] = {0};
int i;
printf("Enter UPPERCASE\n");
fgets(UPPER, BUFSIZE, stdin);
for(i = 0; i < BUFSIZE; i++)
{
if (UPPER[i] >= 65 && UPPER[i] <= 90)
{
UPPER[i] = UPPER[i] + 32;
}
}
printf("The UPPERCASE now is %s", UPPER);
printf("Enter LOWERCASE\n");
fgets(LOWER, BUFSIZE, stdin);
for(i = 0; i < BUFSIZE; i++)
{
if (LOWER[i] >= 97 && LOWER[i] <= 122)
{
LOWER[i] = LOWER[i] - 32;
}
}
printf("The LOWERCASE now is %s", LOWER);
return 0;
}
You should separately add getchar();, after printf("The UPPERCASE now is %c\n", UPPER);
and again after printf("The lowercase now is %c\n", LOWER);.
Most of the program is ending with getch(),and so we think that getch() is used to display the output...but it is wrong.It is used to get a single character from the console.
your correct code should be like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char UPPER, LOWER;
printf("Enter UPPERCASE\n");
UPPER = getchar();
if (UPPER >= 65 && UPPER <= 90)
{
UPPER = UPPER + 32;
printf("The UPPERCASE now is %c\n", UPPER);
}
getchar();
printf("Enter lowercase\n");
LOWER = getchar();
if (LOWER >= 97 && LOWER <= 122)
{
LOWER = LOWER - 32;
printf("The lowercase now is %c\n", LOWER);
}
getchar();
}
Need to match integer type but it must be only separated integer. Example:
INTEGER (-?[0-9]+)
NOTENDLINE [^$]
%%
{INTEGER}/{NOTENDLINE} {}
%%
If I enter string like "23test", it must be wrong and no integer matched. But my solution don't working as needed. I don't know, what I need in NOTENDLINE.
Would this work for you? It relies on the fact that the lexer will find the longest matched rule, but if two are equal, the first rule will be used.
%option noyywrap
DIGIT [0-9]
OTHER [a-z0-9]*
%%
{DIGIT}+ printf( "Integer: %s (%d)\n", yytext, atoi( yytext ) );
{OTHER} printf( "Other: %s\n", yytext );
[ \t\n]+ /* eat up whitespace */
%%
int main( int argc, char **argv )
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
}
Sample Input (file):
test
test123
123
123test
Sample Ouput:
Other: test
Other: test123
Integer: 123 (123)
Other: 123test
If you want to match an integer but only if it is followed by whitespace, do so directly:
-?[[:digit:]]+/[[:space:]]
That will fail if the integer is at the very end of the file without a newline, but text files are not supposed to end with anything other than a newline character. You can, however, do the following:
-?[[:digit:]]+/[[:space:]] { /* Handle an integer */ }
-?[[:digit:]]+/. { /* Handle the error */ }
-?[[:digit:]]+ { /* Handle an integer; this one must be at EOF */ }
I have to make a calculator in flex/bison for a lab in class and I have to add functionality to compute square roots or absolute values in they put in sqrt(x) or abs(x). I imported the math library and I got the caculator to work if the COMMAND FOR IT CONSIST OF ONE CHARACTER. Here's what I mean:
expr:
......
| '(' expr ')' { $$ = fabs($2); } //for abs
| '[' expr ']' {$$ = sqrt($2); } //for sqrt
.......
now, this works fine and if i put in (-2) i get 2, or [4] = 2. The problem is clearly, i need to make it so the command is abs(x) and sqrt(x). If I switch the code to say
| "abs(" expr ')' { $$ = fabs($2); } //for abs
| "sqrt" expr ']' {$$ = sqrt($2); } //for sqrt
this doesn't work because it sees the a then b, and tries to do something with that. This is likely because my calculator also supports assigning variable values (like x=2), so it thinks there should be an operator between a and b. I unfortunately have no idea how to fix this. I would appreciate any help.
Here's my code if that helps:
hexcalc.y
%{
#include <stdio.h>
#include <math.h>
#include <stdlib.h> // often required
// A simple error message to move things along
void yyerror(const char *msg)
{
printf("ERROR(PARSER): %s\n", msg);
}
// Storage for variables: yes Virginia, only 26 variables possible in this langu$
long variables[26];
%}
%union {
float nvalue;
int ivalue;
int varindex;
}
%token <nvalue> NUMBER
%token <ivalue> INT
%token <varindex> NAME
%type <nvalue> expr
%type <nvalue> term
%type <nvalue> varOrNum
%%
statementList : statement '\n'
| statement '\n' statementList
;
statement : NAME '=' expr { variables[$1] = $3; }
| expr { printf("RESULT: %f\n", $1); }
;
expr: expr '+' term { $$ = $1 + $3; }
| expr '-' term { $$ = $1 - $3; }
| '-' term { $$ = 0 - $2; }
| "abs(" expr ')' { $$ = $2; }
| "sqrt(" expr ')' { $$ = sqrt($2); }
| expr '/' term { $$ = $1 / $3; }
| term { $$ = $1; }
;
term : term '*' varOrNum { $$ = $1 * $3; }
| varOrNum { $$ = $1; }
;
varOrNum : NUMBER { $$ = $1; }
| NAME { $$ = variables[$1]; }
;
%%
main() {
int i;
for (i=0; i<26; i++) variables[i] = 0;
yyparse();
}
hexcalc.l
%{
#include <stdlib.h>
#include <math.h>
#include "hexcalc.h"
#define BASE 10
char* endptr;
%}
%%
[a-z] { yylval.varindex = yytext[0] - 'a'; $
}
[0-9]+ { yylval.nvalue = atof(yytext);
return NUMBER;
}
[0-9]+"."[0-9]+?|"."[0-9]+? {yylval.nvalue = atof(yytext);
return NUMBER;
}
[ \t] ;
\n|. { return yytext[0];
}
%%
int yywrap() {
return 1;
}
You need to recognize multicharacter names in the lexer as single tokens and then use them in your grammar. The easy way is to just add them to your lexer:
abs { return ABS; }
sqrt { return SQRT; }
Then you can add to your parser:
%token ABS SQRT
%%
expr: ABS '(' expr ')' { $$ = fabs($3); }
| SQRT '(' expr ')' { $$ = sqrt($3); }
You need to create rules in your .l file for "abs" and "sqrt"; declare the tokens they will each return via %token; and use those token names in the grammar rules: ABS "(" expr ")" : ...
You should have a look at Bison's documentation where a more scalable solution for predefined functions is given (using a symbol table).
http://www.gnu.org/software/bison/manual/html_node/Multi_002dfunction-Calc.html
I'm trying to draw a line, broken out into segments dependent on values. For example, if there are 5 fields, and all 5 fields were true, then my Line would look like
-----
If say the first and last fields were true, and everything else would be false, then it would be
- -
I thought I could do this with a bit mask of some sort. First of all, I've never done a bit mask before, but I think I've seen them here and there. I was wondering how I could go about this, and use enumerations instead of 1/0 for readability. As far as I can see from my data, I would only need values of either 1 or 0 for the different properties. However, it would be good to know how to have one of the values be a three level or higher enumeration for future reference. Thanks!
Trying to do something like:
enum CodingRegions {
Coding = 0x01,
NonCoding = 0x02
};
enum Substitution {
Synonymous = 0x04,
NonSynonmous = 0x05
};
Then based on the value of the object, I could do
bitmask???? = object.CodingRegion | object.Substitution;
Then later, check the value of the bitmask somehow, and then draw the line accordingly based on what the values are.
Not sure exactly what your requirements are, but here is one way it might be written in C:
#include <stdio.h>
typedef enum MyField_ {
hasWombat = 1 << 0,
hasTrinket = 1 << 1,
hasTinRoof = 1 << 2,
hasThreeWheels = 1 << 3,
myFieldEnd = 1 << 4,
} MyField;
void printMyField(MyField data) {
MyField field = 1;
while (field != myFieldEnd) {
printf("%c", data & field ? '-' : ' ');
field <<= 1;
}
printf("\n");
}
int main() {
MyField data = hasTrinket | hasThreeWheels;
printMyField(data);
data |= hasWombat; // set a field
data &= ~hasTrinket; // clear a field
printMyField(data);
return 0;
}
Not sure this is what you want, but:
// assumed Coding/NonCoding, Synonomous/NonSynonymous are opposites of each other. If not, add more bit fields
enum CodingRegions
{
Coding = 1 << 0
} ;
enum Substitution
{
Synonymous = 1 << 1
}
void PrintBitmask( NSUInteger bitmask )
{
printf( "%s", bitmask & Coding != 0 ? "-" : " " ) ;
printf( "%s", bitmask & Substitution != 0 ? "-" : " " ) ;
printf( "\n" ) ;
}
Your PrintBitmask() could also look like this:
void PrintBitmask( NSUInteger bitmask )
{
printf( "%s", bitmask & Coding != 0 ? "Coding" : "Noncoding" ) ;
printf( "|" ) ;
printf( "%s", bitmask & Substitution != 0 ? "Synonymous-" : "Nonsynonymous" ) ;
printf( "\n" ) ;
}
/* I prefer macros over enums (at least for something this simple) */
#define SPACE 0x0
#define DASH 0x1
/* input fields */
int fields[5] = {DASH,SPACE,SPACE,SPACE,DASH};
/* create bitmask */
for (int i=0; i<5; i++) {
mask |= (fields[i] << i);
}
/* interpret bitmask and print the line */
for (int i=0; i<5; i++) {
if (mask & (fields[i] << i)) {
printf("%c", '-');
} else {
printf("%c", ' ');
}
}
Say I have a large number (integer or float) like 12345 and I want it to look like 12,345.
How would I accomplish that?
I'm trying to do this for an iPhone app, so something in Objective-C or C would be nice.
Here is the answer.
NSNumber* number = [NSNumber numberWithDouble:10000000];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
[numberFormatter setGroupingSeparator:#","];
NSString* commaString = [numberFormatter stringForObjectValue:number];
[numberFormatter release];
NSLog(#"%# -> %#", number, commaString);
Try using an NSNumberFormatter.
This should allow you to handle this correctly on an iPhone. Make sure you use the 10.4+ style, though. From that page:
"iPhone OS: The v10.0 compatibility mode is not available on iPhone OS—only the 10.4 mode is available."
At least on Mac OS X, you can just use the "'" string formatter with printf(3).
$ man 3 printf
`'' Decimal conversions (d, u, or i) or the integral portion
of a floating point conversion (f or F) should be
grouped and separated by thousands using the non-mone-
tary separator returned by localeconv(3).
as in printf("%'6d",1000000);
Cleaner C code
// write integer value in ASCII into buf of size bufSize, inserting commas at tousands
// character string in buf is terminated by 0.
// return length of character string or bufSize+1 if buf is too small.
size_t int2str( char *buf, size_t bufSize, int val )
{
char *p;
size_t len, neg;
// handle easy case of value 0 first
if( val == 0 )
{
a[0] = '0';
a[1] = '\0';
return 1;
}
// extract sign of value and set val to absolute value
if( val < 0 )
{
val = -val;
neg = 1;
}
else
neg = 0;
// initialize encoding
p = buf + bufSize;
*--p = '\0';
len = 1;
// while the buffer is not yet full
while( len < bufSize )
{
// put front next digit
*--p = '0' + val % 10;
val /= 10;
++len;
// if the value has become 0 we are done
if( val == 0 )
break;
// increment length and if it's a multiple of 3 put front a comma
if( (len % 3) == 0 )
*--p = ',';
}
// if buffer is too small return bufSize +1
if( len == bufSize && (val > 0 || neg == 1) )
return bufSize + 1;
// add negative sign if required
if( neg == 1 )
{
*--p = '-';
++len;
}
// move string to front of buffer if required
if( p != buf )
while( *buf++ = *p++ );
// return encoded string length not including \0
return len-1;
}
I did this for an iPhone game recently. I was using the built-in LCD font, which is a monospaced font. I formatted the numbers, ignoring the commas, then stuck the commas in afterward. (The way calculators do it, where the comma is not considered a character.)
Check out the screenshots at RetroJuJu. Sorry--they aren't full-sized screenshots so you'll have to squint!
Hope that helps you (it's in C) :
char* intToFormat(int a)
{
int nb = 0;
int i = 1;
char* res;
res = (char*)malloc(12*sizeof(char));
// Should be enough to get you in the billions. Get it higher if you need
// to use bigger numbers.
while(a > 0)
{
if( nb > 3 && nb%3 == 0)
res[nb++] = ',';
// Get the code for the '0' char and add it the position of the
// number to add (ex: '0' + 5 = '5')
res[nb] = '0' + a%10;
nb++;
a /= 10;
}
reverse(&res);
return res;
}
There might be a few errors I didn't see (I'm blind when it comes to this...)
It's like an enhanced iToA so maybe it's not the best solution.
Use recursion, Luke:
#include <stdio.h>
#include <stdlib.h>
static int sprint64u( char* buffer, unsigned __int64 x) {
unsigned __int64 quot = x / 1000;
int chars_written;
if ( quot != 0) {
chars_written = sprint64u( buffer, quot);
chars_written += sprintf( buffer + chars_written, ".%03u", ( unsigned int)( x % 1000));
}
else {
chars_written = sprintf( buffer, "%u", ( unsigned int)( x % 1000));
}
return chars_written;
}
int main( void) {
char buffer[ 32];
sprint64u( buffer, 0x100000000ULL);
puts( buffer);
return EXIT_SUCCESS;
}