27

What does the following line do?

#line 25 "CSSGrammar.y"

And what's with the extension?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Just out of curiosity... Which compiler does eat this? – Vyktor Feb 05 '12 at 20:47
  • 1
    @Vyktor it's part of the standard – Seth Carnegie Feb 05 '12 at 20:48
  • I'm sure this is a duplicate. See this: http://gcc.gnu.org/onlinedocs/cpp/Line-Control.html – Pubby Feb 05 '12 at 20:49
  • 4
    Duuude... First link out of google: http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc09lc.htm – Vyktor Feb 05 '12 at 20:49
  • @Vyktor when searching for what? I did try google, but to no luck. – Luchian Grigore Feb 05 '12 at 20:51
  • @LuchianGrigore I just type in "#line" into google and got a relevant result – Seth Carnegie Feb 05 '12 at 20:52
  • 1
    @Vyktor :)) Right, I didn't think google accepts hash signs. – Luchian Grigore Feb 05 '12 at 20:54
  • :))) give yourself a facepalm :P (man I'm laughing so hard :D) and mark Seth's answer as answer he put up great job putting it together – Vyktor Feb 05 '12 at 20:55
  • @Vyktor I already upvoted, but I'm still waiting for an explanation on the extension. – Luchian Grigore Feb 05 '12 at 20:58
  • Isn't that obvious from link I provided? I allows you to "*spoof*" value of `__LINE__` and `__FILE__` "macros" and errors will be reported on different line. – Vyktor Feb 05 '12 at 21:01
  • @LuchianGrigore also that's clear from what the standard says: _sets the presumed line number similarly and **changes the presumed name of the source file to be the contents of the character string literal**._ Someone just chose the `.y` extension, which is used by YACC IIRC (also it's called "grammar" so that would make sense) – Seth Carnegie Feb 05 '12 at 21:12

7 Answers7

20

According to the Standard:

§16.4.3:

A preprocessing directive of the form

# line digit-sequence new-line

causes the implementation to behave as if the following sequence of source lines begins with a source line that has a line number as specified by the digit sequence (interpreted as a decimal integer). If the digit sequence specifies zero or a number greater than 2147483647, the behavior is undefined.

§16.4.4:

A preprocessing directive of the form

# line digit-sequence " s-char-sequenceopt" new-line

sets the presumed line number similarly and changes the presumed name of the source file to be the contents of the character string literal.

§16.4.5:

A preprocessing directive of the form

# line pp-tokens new-line

(that does not match one of the two previous forms) is permitted. The preprocessing tokens after line on the directive are processed just as in normal text (each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined; otherwise, the result is processed as appropriate.

The .y extension is just what the author chose to use, perhaps to make it apparent that it was a YACC file (the word "grammar" also points to that though it's just a guess).

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
12

It simply states that the current line of code is sourced from line 25 of CSSGrammar.y, a YACC-style grammar file which is where this code was generated.

This can be used by debuggers to step into the grammar itself as opposed to the generated code.

user7116
  • 63,008
  • 17
  • 141
  • 172
8

#line directive modifies the reporting position for the compiler, and is used by code generating software to help the programmer identify the issue in the original source. It can be used by anyone to help redirect error reporting to be more informative.

So for instance your parser generates a CSSGrammar.cpp file say, which is compiled by the c++ compiler, and has c++ snippets in it, a #line 25 "CSSGrammar.y" directive tells the c++ compiler to treat that particular point in the file as if it is line number 25 from CSSGrammar.y

The compiler will continue to parse subsequent lines and report errors under the initial conditions of that directive.

So if an error occurs 3 lines later it would report that an error occurred on line 28 in CSSGrammar.y

Note that a single source file can have sources coming in from multiple parts; and that this directive can be used quite effectively to indicate error conditions.

Typically you'll see that there are multiple #line directives along the way; they are just there to account for various injections along the way (to reset the reporting caret if you will).

Note that #line directive can be used by ANY generator including your own, and is not limited to in anyway parser generators.

Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
3

It a directive for the compiler to believe that the following line is the line number 25 in file CSSGrammar.y. Then, if an error is detected by the compiler on the 2nd next line, it would be reported as coming from line 26 of CSSGrammar.y

Programs generating C files, like bison, or yacc, or flex, or ANTLR, or even the (obsolete) MELT use that possibility a lot.

If debugging information is generated (e.g. with gcc -g), it will point to the CSSGrammar.y file in your example.

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

The 'yacc' parser generator consumes files that end in .y, and emits files that contain c or c++. It adds these #line lines to allow a debugger to get back to ye olde original source, accept no substitutes.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
2

it's a c preprocessor option. It tells the c-parser to drop it's line count of the source file an pretend, that this is line #25.

With this information it's easier for you to debug the the source file. The yacc file will be translated into a c-source, where this is the pretended source line.

Jörg Beyer
  • 3,631
  • 21
  • 35
0

Using #line forces the compiler to experience amnesia about what file it's compiling and what line it's on, and loads in the new data.

Note: The compiler still compiles from the line it was on.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
PoolloverNathan
  • 148
  • 2
  • 11