2

I was playing with flex and bison today, and something kind of eerie came to my attention.

localhost:c math4tots$ lex c.l
localhost:c math4tots$ yacc -d c.y
localhost:c math4tots$ rm c.l c.y
localhost:c math4tots$ gcc c.c lex.yy.c y.tab.c
c.y: In function ‘opr’:
c.y:120: error: ‘nodeType’ has no member named ‘oper’

I've only passed c.c lex.yy.c, and y.tab.c (c.h and y.tab.h are also included as headers), but somehow gcc knows about c.l and c.y. In fact, even after I've deleted c.l and c.y, gcc knows where in c.y the error in the code was. How does it do that?

I feel like I've seen something similar for some different tools I've used in the past, but I can't exactly remember what they were.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
math4tots
  • 8,540
  • 14
  • 58
  • 95

2 Answers2

3

You'll find some markers in your files along the lines of:

#line 75 "c.y"

which is used for exactly this purpose, the ability to report error messages or warnings against the original file that produced the actual files you're compiling.

It's basically so that you don't have to go to the c.c file and try to figure out the equivalent line in the c.y file that you have to fix.

In this sense, the C file is no different to an object file. You don't care what's in it since it's automatically generated. If there's a problem with it, you want to be able to go directly back to the right line in c.y and fix it at the source.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
2

The generated C file has some line control preprocessor directives (also generated) like

 #line 119 "c.y"

and then the compiler believes that the next line after this directive is in file c.y at line 119 and compute following positions accordingly.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547