News for hackers. Stuff that matters.
Re:Scandalous Weird Old Things About The C Preprocessor (2015) by klodolph on Tuesday May 30, 2017 @10:05AM (#14445425)
A nit: the comment about how the C preprocessor can't be described by a context-free grammar is followed by a comment about how # directives are sensitive to where they are in the line. That's actually a non-sequitur! It's totally possible for context-free grammars to be line-oriented, the "context" in this sense has a very technical meaning--it means that the left side of a production rule must have only one symbol (i.e. no context).
Re:Scandalous Weird Old Things About The C Preprocessor (2015) by yorwba on Tuesday May 30, 2017 @10:33AM (#14445636)
Yes, the real reason C preprocessor syntax can't be described by a context-free grammar is that parsing and execution are interleaved. This requires the parser to carry the set of current macro definitions for each parsing decisions, which implies non-context-freeness.

However, see [0] for a way to parse C with preprocessor #ifdefs (but after expanding #includes and #defines).

[0] "SuperC : Parsing All of C by Taming the Preprocessor" http://cs.nyu.edu/rgrimm/papers/pldi12.pdf

Re:Scandalous Weird Old Things About The C Preprocessor (2015) by robertelder on Tuesday May 30, 2017 @11:39AM (#14446080)
Can you give me an example grammar to help visualize your statement? I can probably make a note or clarification. I think one other point I forgot to mention was that the production rule for the # directives would have to look something like

    include-directive:
        beginning-of-file # INCLUDE ...
        newline-from-previous-line # INCLUDE ...
Since 'beginning-of-file' isn't really something you can reduce to a token I justified that it would be context sensitive.
Re:Scandalous Weird Old Things About The C Preprocessor (2015) by kpxxx on Tuesday May 30, 2017 @12:35PM (#14446506)
> Since 'beginning-of-file' isn't really something you can reduce to a token...

Of course you can, generate a token immediately upon opening a file. Nothing special about b-o-f or b-o-l. Similar to EOF.

Re:Scandalous Weird Old Things About The C Preprocessor (2015) by chubot on Tuesday May 30, 2017 @12:39PM (#14446531)
FWIW, I haven't thought too much about the case of the preprocessor, but this series of blog posts might help:

http://trevorjim.com/how-to-prove-that-a-programming-languag...

My initial thoughts are that the property of being context-free only refers to a parser, not to the lexer. A lexer can be line-oriented, as mentioned.

The blog post mentions the lexer issue. The definition of a context-free language is fuzzy because you could have an infinitely powerful lexer, but he gives a precise definition.

Re:Scandalous Weird Old Things About The C Preprocessor (2015) by klodolph on Tuesday May 30, 2017 @04:24PM (#14448246)
In the strictest sense, "context-free" applies to either a grammar or a language. A language is context-free if there exists a context-free grammar for it, but there might be several grammars for the same language.

The lexical syntax is usually a "regular language" or quite close to one, this includes C. All regular languages are also context-free, the set of regular languages is a strict subset of the context-free languages. Regular languages can be parsed using regular expressions.

And again, there's nothing wrong with being line-oriented. That's not "more powerful" in any sense of the term. Recognizing newlines, SOF, EOF, etc. are really simple things (in the language hierarchy sense) that you can do in regular expressions without using any extensions that make them non-regular (like backreferences), therefore they can be converted to a context-free grammar.

Commonly, a programming language will have regular expressions for its lexer and a context-free grammar for its parser. Since the lexer is technically also context-free, it's possible to combine the lexer and parser into a single stage, but this is a bad idea for various software engineering reasons.

Some older languages have context-free parsers, like C, whose grammar is not context-free (that's not the same as "context-sensitive" which is a particular technical term). One major reason C's grammar is not context-free because it has to distinguish between typedefs and other identifiers.

Of course, a language as a whole is almost never context-free, but we usually use "context-free" to mean that the parser and lexer are context-free.

Re:Scandalous Weird Old Things About The C Preprocessor (2015) by chubot on Wednesday May 31, 2017 @05:33AM (#14451278)
I don't think most languages in widespread use have lexers that are regular. Here the same author gives the example of Python's indentation requiring a stack: http://trevorjim.com/python-is-not-context-free/

Also Haskell: http://trevorjim.com/haskell-is-not-context-free/

I'm pretty sure in JavaScript that the /s+/ regex syntax can't be recognized with a regular language. Perl is of course insane -- it's not even statically parseable [1]. Shell isn't context-free.

The theme of this set of posts is that most languages used in practice aren't expressible with CFGs, and I agree. I didn't prove it but he shows how you would prove it.

[1] http://www.oilshell.org/blog/2016/10/20.html (see the end of this post for links about C++, Perl, Make)

Re:Scandalous Weird Old Things About The C Preprocessor (2015) by xigency on Tuesday May 30, 2017 @11:56AM (#14446208)
The best explanation is that context free languages are a superset of regular languages, and it's totally possible to write a regular expression without any extensions for that case: (^|\n)#\s*INCLUDE.