my file myComp.l
%{
#include <stdlib.h>
#include <stdio.h>
#include "y.tab.h"
int yyerror(char *);
%}
%%
[a-z] {
yylval = *yytext - 'a';
return VAR;
}
[0-9]+ {
yylval = atoi(yytext);
return INT;
}
[-+()=/*\n] { return *yytext; } [ \t] ;
. { yyerror("Input non valido"); }
%% int yywrap(void){
return 1; }
and this is the file myComp.y
%{ /* Prologo */
#define YYSTYPE int
#include <math.h>
#include <stdio.h>
int yyerror(char *);
int yylex(void) ;
int sym[26];
%}
/* Definizioni */
%token INT VAR
%left '+' '-'
%left '*' '/'
%%
program:
program statement '\n'
|
;
statement:
expr { printf("%d\n", $1); }
| VAR '=' expr { sym[$1] = $3; }
;
expr:
INT
| VAR { $$ = sym[$1]; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| '(' expr ')' { $$ = $2; }
;
%%
int yyerror(char *s) {
fprintf(stderr, "%s\n", s);
return 1;
}
int main( void ) {
yyparse();
return 0;
}
i used this commands for compiling
flex myComp.l
bison -y myComp.y
gcc -o myComp y.tab.c
but i have this error:
/tmp/ccaHRWZu.o: In function `yyparse':
y.tab.c:(.text+0x24a): undefined reference to `yylex'
collect2: ld returned 1 exit status
all programs that i installed are updated in the last version.i can't unterstand where is the problem?what i can i do for risolving this error.please help me to fix it.thanks all
thk's all
you are missing the linker flag -lfl to link your parser against the flex library where yylex is defined. Additionally you need to build the output of flex, too. That c-file is probably called: myComp.lex.c
compile with:
gcc -o myComp y.tab.c myComp.lex.c -lfl
Related
I wonder where the parser specification below went wrong. The parser aims to parse and evaluate an expression like 2+3*4 to 14. It is to be run with FsLexYacc.
%{
%}
%token <int> CSTINT
%token PLUS MINUS MUL
%token LPAR RPAR
%token EOF
%left MINUS PLUS /* lowest precedence */
%left TIMES DIV /* highest precedence */
%start Main
%type int Main
%%
Main:
Expr EOF { $1 }
;
Expr:
| CSTINT { $1 }
| MINUS CSTINT { - $2 }
| LPAR Expr RPAR { $2 }
| Expr MUL Expr { $1 * $3 }
| Expr PLUS Expr { $1+$3 }
| Expr MINUS Expr { $1-$3 }
;
I got the error
ExprPar.fsy(18,0): error: Unexpected character '%'%
The line 18 refers to the line up before "Main". Where is the bug?
I believe the type specified by %type should be in angle brackets:
%type <int> Main
HERE IS MY YACC
%{
#include <stdio.h>
#include <ctype.h>
#include "lex.yy.c"
void yyerror (s) /* Called by yyparse on error */
char *s;
{
printf ("%s\n", s);
}
%}
%start program
%union{
int value;
char * string;
}
%token <value> NUM INT VOID WHILE IF THEN ELSE READ WRITE RETURN LE GE EQ NE
%token <string> ID
%token <value> INTEGER
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS
%%
program : decllist
{fprintf(stderr, "program");}
;
decllist : dec
{fprintf(stderr, "\n dec");}
| dec decllist
;
dec : vardec
{fprintf(stderr, "vardec");}
| fundec
{fprintf(stderr, "YEAH");}
;
typespec : INT
| VOID
;
vardec : typespec ID ';'
{fprintf(stderr, "yep");}
| typespec ID '[' NUM ']' ';'
{fprintf(stderr, "again");}
;
fundec : typespec ID '(' params ')' compoundstmt
;
params : VOID
| paramlist
;
paramlist : param
| param ',' paramlist
;
param : typespec ID
| typespec ID '['']'
;
compoundstmt : '{' localdeclerations statementlist '}'
;
localdeclerations :/* empty */
|vardec localdeclerations
;
statementlist : /* empty */
| statement statementlist
;
statement : expressionstmt
| compoundstmt
| selectionstmt
| iterationstmt
| assignmentstmt
| returnstmt
| readstmt
| writestmt
;
expressionstmt : expression ';'
| ';'
;
assignmentstmt : var '=' expressionstmt
;
selectionstmt : IF '(' expression ')' statement
| IF '(' expression ')' statement ELSE statement
;
iterationstmt : WHILE '(' expression ')' statement
;
returnstmt : RETURN ';'
| RETURN expression ';'
;
writestmt : WRITE expression ';'
;
readstmt : READ var ';'
;
expression : simpleexpression
;
var : ID
| ID '[' expression ']'
;
simpleexpression : additiveexpression
| additiveexpression relop simpleexpression
;
relop : LE
| '<'
| '>'
| GE
| EQ
| NE
;
additiveexpression : term
| term addop term
;
addop : '+'
| '-'
;
term : factor
| term multop factor
;
multop : '*'
| '/'
;
factor : '(' expression ')'
| NUM
| var
| call
;
call : ID '(' args ')'
;
args : arglist
| /* empty */
;
arglist : expression
| expression ',' arglist
;
%%
main(){
yyparse();
}
AND HERE IS MY LEX
%{
int mydebug=1;
int lineno=0;
#include "y.tab.h"
%}
%%
int {if (mydebug) fprintf(stderr, "int found\n");
return(INT);
}
num {if (mydebug) fprintf(stderr, "num found\n");
return(NUM);
}
void {if (mydebug) fprintf(stderr, "void found \n");
return(VOID);
}
while {if (mydebug) fprintf(stderr, "while found \n");
return(WHILE);
}
if {if (mydebug) fprintf(stderr, "if found \n");
return(IF);
}
then {if (mydebug) fprintf(stderr, "then found \n");
return(THEN);
}
else {if (mydebug) fprintf(stderr, "else found \n");
return(ELSE);
}
read {if (mydebug) fprintf(stderr, "read found \n");
return(READ);
}
write {if (mydebug) fprintf(stderr, "void found \n");
return(WRITE);
}
return {if (mydebug) fprintf(stderr, "void found \n");
return(RETURN);
}
'<=' {if (mydebug) fprintf(stderr, "void found \n");
return(LE);
}
'>=' {if (mydebug) fprintf(stderr, "void found \n");
return(GE);
}
'==' {if (mydebug) fprintf(stderr, "void found \n");
return(EQ);
}
'!=' {if (mydebug) fprintf(stderr, "void found \n");
return(NE);
}
[a-zA-Z][a-zA-Z0-9]* {if (mydebug) fprintf(stderr,"Letter found\n");
yylval.string=strdup(yytext); return(ID);}
[0-9][0-9]* {if (mydebug) fprintf(stderr,"Digit found\n");
yylval.value=atoi((const char *)yytext); return(NUM);}
[ \t] {if (mydebug) fprintf(stderr,"Whitespace found\n");}
[=\-+*/%&|()\[\]<>;] { if (mydebug) fprintf(stderr,"return a token %c\n",*yytext);
return (*yytext);}
\n { if (mydebug) fprintf(stderr,"cariage return %c\n",*yytext);
lineno++;
return (*yytext);}
%%
int yywrap(void)
{ return 1;}
If i type in something like 'int a;' it gets all the way to the new line and prints 'carriage returned' but then stops and spits out syntax error at the end. Can anyone see why?
I have gone over this a lot and can't seem to find what keeps stopping it. I have a previous program that i am going back to trying to see if i can't figure it out but i'm stumped. Can anyone help?
Your lexer is returning '\n' (newline) tokens at the end of the line, but your parser never accepts them, so you'll get a syntax error when the parser hits the first newline.
I am getting the above error when using Freds ImageMagick Textdeskew Script The error looks like this:
awk: line 38: syntax error at or near *
/home/work/textdeskew: line 468: regression_Arr: bad array subscript
/home/work/textdeskew: line 474: regression_Arr: bad array subscript
The lines the errors fall on look like this:
angle=`echo ${regression_Arr[rnum-1]} | cut -d: -f2` line 468
# set rotation to be correct for -90<=angle<90 (+90 will be upside downs)
rotation=`convert xc: -format "%[fx:$angle<0?-($angle+90):-($angle-90)]" info:`
rotation=`convert xc: -format "%[fx:abs($rotation)<0.00001?0:$rotation]" info:`
# remove outliers, if res_ave > res_thresh
res_ave=`echo ${regression_Arr[rnum-7]} | cut -d: -f2` line 474
Im assuming the error is because rnum is 0. But im unsure on how to read and debug the script to resolve the error as this may not even be the case. Here is where rnum and regression_Arr are declared:
linearRegression()
{
Arr="$1"
regression_Arr=(`echo "${Arr[*]}" | awk \
'BEGIN { FS = ","; RS = " "; pi = atan2(0, -1); }
NF == 2 { x_sum += $1
y_sum += $2
xy_sum += $1*$2
x2_sum += $1*$1
y2_sum += $2*$2
num += 1
x[NR] = $1
y[NR] = $2
}
END { mean_x = x_sum / num
mean_y = y_sum / num
for (i = 1; i <= num; i++) {
delx = (x[i]-mean_x)
dely = (y[i]-mean_y)
numerator += delx*dely
denominator += dely*dely - delx*delx
}
phi = 0.5*atan2(-2*numerator,denominator)
r = mean_x*cos(phi)+mean_y*sin(phi)
if ( sqrt(phi*phi) < 0.0001 ) {
angle = -90
}
else {
slope = -cos(phi)/sin(phi)
inter = r/sin(phi)
angle = (180/pi)*atan2(slope,1)
}
for (j = 1; j <= num; j++) {
delr = (x[j]*cos(phi)+y[j]*sin(phi)-r)
res_sq = delr*delr
sum_res_sq += res_sq
res = sqrt(delr*delr)
sum_res += res
print "Residual"j":"res
}
res_ave = sum_res/num
res_std = sqrt((sum_res_sq/num)-(sum_res/num)**2)
print "res_ave:"res_ave
print "res_std:"res_std
print "phi:"phi
print "r:"r
print "Slope:"slope
print "Intercept:"inter
print "Angle:"angle
}'`)
rnum=${#regression_Arr[*]}
if $debug; then
echo ""
echo "rnum=$rnum;"
# list regression data
for ((ii=0; ii<rnum; ii++)); do
echo "${regression_Arr[$ii]}"
done
fi
}
I wonder if this script used to work and now doesnt due to updates in the code?
This was fixed by installing gawk and following a new error bc. Huge thanks to #fmw42 for helping through this on the ImageMagick forums.
Let me be specific. We have a csv file consists of 2 columns x and y like this:
x,y
1h,a2
2e,a2
4f,a2
7v,a2
1h,b6
4f,b6
4f,c9
7v,c9
...
And we want to count how many shared x values two y values have, which means we want to get this:
y1,y2,share
a2,b6,2
a2,c9,2
b6,c9,1
And b6,a2,2 should not show up. Does anyone know how to do this by awk? Or anything else?
Thx ahead!
Try this executable awk script:
#!/usr/bin/awk -f
BEGIN {FS=OFS=","}
NR==1 { print "y1" OFS "y2" OFS "share" }
NR>1 {last=a[$1]; a[$1]=(last!=""?last",":"")$2}
END {
for(i in a) {
cnt = split(a[i], arr, FS)
if( cnt>1 ) {
for(k=1;k<cnt;k++) {
for(i=2;i<=cnt;i++) {
if( arr[k] != arr[i] ) {
key=arr[k] OFS arr[i]
if(out[key]=="") {order[++ocnt]=key}
out[key]++
}
}
}
}
}
for(i=1;i<=ocnt;i++) {
print order[i] OFS out[order[i]]
}
}
When put into a file called awko and made executable, running it like awko data yields:
y1,y2,share
a2,b6,2
a2,c9,2
b6,c9,1
I'm assuming the file is sorted by y values in the second column as in the question( after the header ). If it works for you, I'll add some explanations tomorrow.
Additionally for anyone who wants more test data, here's a silly executable awk script for generating some data similar to what's in the question. Makes about 10K lines when run like gen.awk.
#!/usr/bin/awk -f
function randInt(max) {
return( int(rand()*max)+1 )
}
BEGIN {
a[1]="a"; a[2]="b"; a[3]="c"; a[4]="d"; a[5]="e"; a[6]="f"
a[7]="g"; a[8]="h"; a[9]="i"; a[10]="j"; a[11]="k"; a[12]="l"
a[13]="m"; a[14]="n"; a[15]="o"; a[16]="p"; a[17]="q"; a[18]="r"
a[19]="s"; a[20]="t"; a[21]="u"; a[22]="v"; a[23]="w"; a[24]="x"
a[25]="y"; a[26]="z"
print "x,y"
for(i=1;i<=26;i++) {
amultiplier = randInt(1000) # vary this to change the output size
r = randInt(amultiplier)
anum = 1
for(j=1;j<=amultiplier;j++) {
if( j == r ) { anum++; r = randInt(amultiplier) }
print a[randInt(26)] randInt(5) "," a[i] anum
}
}
}
I think if you can get the input into a form like this, it's easy:
1h a2 b6
2e a2
4f a2 b6 c9
7v a2 c9
In fact, you don't even need the x value. You can convert this:
a2 b6
a2
a2 b6 c9
a2 c9
Into this:
a2,b6
a2,b6
a2,c9
a2,c9
That output can be sorted and piped to uniq -c to get approximately the output you want, so we only need to think much about how to get from your input to the first and second states. Once we have those, the final step is easy.
Step one:
sort /tmp/values.csv \
| awk '
BEGIN { FS="," }
{
if (x != $1) {
if (x) print values
x = $1
values = $2
} else {
values = values " " $2
}
}
END { print values }
'
Step two:
| awk '
{
for (i = 1; i < NF; ++i) {
for (j = i+1; j <= NF; ++j) {
print $i "," $j
}
}
}
'
Step three:
| sort | awk '
BEGIN {
combination = $0
print "y1,y2,share"
}
{
if (combination == $0) {
count = count + 1
} else {
if (count) print combination "," count
count = 1
combination = $0
}
}
END { print combination "," count }
'
This awk script does the job:
BEGIN { FS=OFS="," }
NR==1 { print "y1","y2","share" }
NR>1 { ++seen[$1,$2]; ++x[$1]; ++y[$2] }
END {
for (y1 in y) {
for (y2 in y) {
if (y1 != y2 && !(y2 SUBSEP y1 in c)) {
for (i in x) {
if (seen[i,y1] && seen[i,y2]) {
++c[y1,y2]
}
}
}
}
}
for (key in c) {
split(key, a, SUBSEP)
print a[1],a[2],c[key]
}
}
Loop through the input, recording both the original elements and the combinations. Once the file has been processed, look at each pair of y values. The if statement does two things: it prevents equal y values from being compared and it saves looping through the x values twice for every pair. Shared values are stored in c.
Once the shared values have been aggregated, the final output is printed.
This sed script does the trick:
#!/bin/bash
echo y1,y2,share
x=$(wc -l < file)
b=$(echo "$x -2" | bc)
index=0
for i in $(eval echo "{2..$b}")
do
var_x_1=$(sed -n ''"$i"p'' file | sed 's/,.*//')
var_y_1=$(sed -n ''"$i"p'' file | sed 's/.*,//')
a=$(echo "$i + 1" | bc)
for j in $(eval echo "{$a..$x}")
do
var_x_2=$(sed -n ''"$j"p'' file | sed 's/,.*//')
var_y_2=$(sed -n ''"$j"p'' file | sed 's/.*,//')
if [ "$var_x_1" = "$var_x_2" ] ; then
array[$index]=$var_y_1,$var_y_2
index=$(echo "$index + 1" | bc)
fi
done
done
counter=1
for (( k=1; k<$index; k++ ))
do
if [ ${array[k]} = ${array[k-1]} ] ; then
counter=$(echo "$counter + 1" | bc)
else
echo ${array[k-1]},$counter
counter=1
fi
if [ "$k" = $(echo "$index-1"|bc) ] && [ $counter = 1 ]; then
echo ${array[k]},$counter
fi
done
I want extract all header files between < and >. I have a file called configure.ac from a git-repository. I want know which header files are present in this file. I would like to generate a list file with only header files. Example:
# _NL_MEASUREMENT_MEASUREMENT is an enum and not a define
AC_MSG_CHECKING([for _NL_MEASUREMENT_MEASUREMENT])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <langinfo.h>]],
[[char c = *((unsigned char *) nl_langinfo(_NL_MEASUREMENT_MEASUREMENT));]])],
[nl_ok=yes],
[nl_ok=no])
AC_MSG_RESULT($nl_ok)
if test "$nl_ok" = "yes"; then
AC_DEFINE(HAVE__NL_MEASUREMENT_MEASUREMENT, 1,
[Define to 1 if _NL_MEASUREMENT_MEASUREMENT is available])
fi
if test "$ac_cv_header_sys_shm_h" = "yes"; then
AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
int id;
char *shmaddr;
id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0600);
if (id == -1)
exit (2);
shmaddr = shmat (id, 0, 0);
shmctl (id, IPC_RMID, 0);
if ((char*) shmat (id, 0, 0) == (char*) -1)
{
shmdt (shmaddr);
exit (1);
}
shmdt (shmaddr);
shmdt (shmaddr);
exit (0);
}
]])],
[AC_DEFINE([IPC_RMID_DEFERRED_RELEASE],[1],
[Define to 1 if shared memory segments are released deferred.])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)],
[AC_MSG_RESULT(assuming no)])
AC_DEFINE(USE_SYSV_SHM, 1, [Define to 1 to use SYSV shared memory])
else
shmtype=none
fi
The output file must contain:
langinfo.h
types.h
ipc.h
shm.h
I tried:
echo "#include <stdio.h>" | sed -n 's/.*<\(.*\)\>.*/\1/p'
---> stdio.h
cat configure.ac | sed -n 's/.*<\(.*\)\>.*/\1/p' | sort -u > list.txt
---> It doesn't work
I can't find the error.
It depends a bit on your version of sed. On Mac OS X 10.9.1 Mavericks (BSD sed), this works:
$ sed -n 's/.*\<\(.*\)\>.*/\1/p' data
langinfo.h
sys/types.h
sys/ipc.h
sys/shm.h
$
(where data is the fragment of configure.ac you quote in the question). OTOH, GNU sed (version 4.2.2) gives (with the ... being elided lines):
$ /usr/gnu/bin/sed -n 's/.*\<\(.*\)\>.*/\1/p' data
a
_NL_MEASUREMENT_MEASUREMENT
AC_LINK_IFELSE
AC_LANG_PROGRAM
h
_NL_MEASUREMENT_MEASUREMENT
yes
...
AC_LANG_SOURCE
h
h
h
main
id
shmaddr
...
else
shmtype
fi
$
Change the regex to:
$ /usr/gnu/bin/sed -n 's/.*<\(.*\)>.*/\1/p' data
langinfo.h
sys/types.h
sys/ipc.h
sys/shm.h
$
and the same output with BSD sed.
Moral: by default, the angle brackets <> are not metacharacters and do not need backslash escaping.
When they are escaped, they have a specific meaning (end of word or thereabouts).
perl -lne 'print $1 if(/\<(.*?)\>/)' your_file