#include <stdio.h>
#include <stdlib.h>
typedef void effector(int);
typedef struct transition transition;
struct transition {
int state;
effector *effect;
};
enum sigil { Letter, Slash, Star, EndOfFile, Squote, Dquote, Bslash, Newline };
typedef enum sigil sigil;
sigil sigilify(int c) {
switch (c) {
case '/': return Slash;
case '*': return Star;
case EOF: return EndOfFile;
case '\'': return Squote;
case '"': return Dquote;
case '\\': return Bslash;
case '\n': return Newline;
default: return Letter;
}
}
void nothing (int c) { }
void halt
(int c
) { exit(EXIT_SUCCESS
); }
#define T(state, sigil) (((state) << 4) | sigil)
int main() {
transition state = { 0, emit };
transition table[] = {
[T(0, Slash)] = { 1, nothing },
[T(0, Letter)] = { 0, emit },
[T(0, Star)] = { 0, emit },
[T(0, EndOfFile)] = { 0, halt },
[T(0, Squote)] = { 6, emit },
[T(0, Dquote)] = { 4, emit },
[T(0, Bslash)] = { 0, emit },
[T(0, Newline)] = { 0, emit }, // Handle newline in state 0
[T(1, Slash)] = { 9, nothing }, // Transition to line comment state
[T(1, Star)] = { 2, nothing }, // Start of block comment
[T(1, Letter)] = { 0, slash }, // Not a comment, emit '/'
[T(1, EndOfFile)] = { 0, halt },
[T(1, Squote)] = { 0, slash },
[T(1, Dquote)] = { 0, slash },
[T(1, Bslash)] = { 0, slash },
[T(1, Newline)] = { 0, slash }, // Not a comment, emit '/'
[T(2, Slash)] = { 2, nothing },
[T(2, Letter)] = { 2, nothing },
[T(2, Star)] = { 3, nothing },
[T(2, EndOfFile)] = { 0, halt },
[T(2, Squote)] = { 2, nothing },
[T(2, Dquote)] = { 2, nothing },
[T(2, Bslash)] = { 2, nothing },
[T(2, Newline)] = { 2, nothing }, // Newlines inside block comments are ignored
[T(3, Slash)] = { 0, nothing },
[T(3, Letter)] = { 2, nothing },
[T(3, Star)] = { 2, nothing },
[T(3, EndOfFile)] = { 0, halt },
[T(3, Squote)] = { 2, nothing },
[T(3, Dquote)] = { 2, nothing },
[T(3, Bslash)] = { 2, nothing },
[T(3, Newline)] = { 2, nothing },
[T(4, Slash)] = { 4, emit },
[T(4, Letter)] = { 4, emit },
[T(4, Star)] = { 4, emit },
[T(4, EndOfFile)] = { 0, halt },
[T(4, Squote)] = { 4, emit },
[T(4, Dquote)] = { 0, emit },
[T(4, Bslash)] = { 5, emit },
[T(4, Newline)] = { 4, emit },
[T(5, Slash)] = { 4, emit },
[T(5, Letter)] = { 4, emit },
[T(5, Star)] = { 4, emit },
[T(5, EndOfFile)] = { 0, halt },
[T(5, Squote)] = { 4, emit },
[T(5, Dquote)] = { 4, emit },
[T(5, Bslash)] = { 4, emit },
[T(5, Newline)] = { 4, emit },
[T(6, Slash)] = { 8, emit },
[T(6, Letter)] = { 8, emit },
[T(6, Star)] = { 8, emit },
[T(6, EndOfFile)] = { 0, halt },
[T(6, Squote)] = { 8, emit },
[T(6, Dquote)] = { 8, emit },
[T(6, Bslash)] = { 7, emit },
[T(6, Newline)] = { 8, emit },
[T(7, Slash)] = { 8, emit },
[T(7, Letter)] = { 8, emit },
[T(7, Star)] = { 8, emit },
[T(7, EndOfFile)] = { 8, emit },
[T(7, Squote)] = { 8, emit },
[T(7, Dquote)] = { 8, emit },
[T(7, Bslash)] = { 8, emit },
[T(7, Newline)] = { 8, emit },
[T(8, Slash)] = { 0, emit },
[T(8, Letter)] = { 0, emit },
[T(8, Star)] = { 0, emit },
[T(8, EndOfFile)] = { 0, halt },
[T(8, Squote)] = { 0, emit },
[T(8, Dquote)] = { 0, emit },
[T(8, Bslash)] = { 0, emit },
[T(8, Newline)] = { 0, emit },
// New State 9: Inside Line Comment
[T(9, Slash)] = { 9, nothing },
[T(9, Star)] = { 9, nothing },
[T(9, Letter)] = { 9, nothing },
[T(9, Squote)] = { 9, nothing },
[T(9, Dquote)] = { 9, nothing },
[T(9, Bslash)] = { 9, nothing },
[T(9, Newline)] = { 0, emit }, // End of line comment
[T(9, EndOfFile)] = { 0, halt }, // End of file while in line comment
};
for (;;) {
state = table[T(state.state, sigilify(c))];
state.effect(c);
}
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCnR5cGVkZWYgdm9pZCBlZmZlY3RvcihpbnQpOwp0eXBlZGVmIHN0cnVjdCB0cmFuc2l0aW9uIHRyYW5zaXRpb247CnN0cnVjdCB0cmFuc2l0aW9uIHsKICBpbnQgc3RhdGU7CiAgZWZmZWN0b3IgKmVmZmVjdDsKfTsKCmVudW0gc2lnaWwgeyBMZXR0ZXIsIFNsYXNoLCBTdGFyLCBFbmRPZkZpbGUsIFNxdW90ZSwgRHF1b3RlLCBCc2xhc2gsIE5ld2xpbmUgfTsKdHlwZWRlZiBlbnVtIHNpZ2lsIHNpZ2lsOwoKc2lnaWwgc2lnaWxpZnkoaW50IGMpIHsKICBzd2l0Y2ggKGMpIHsKICAgIGNhc2UgJy8nOiAgcmV0dXJuIFNsYXNoOwogICAgY2FzZSAnKic6ICByZXR1cm4gU3RhcjsKICAgIGNhc2UgRU9GOiAgcmV0dXJuIEVuZE9mRmlsZTsKICAgIGNhc2UgJ1wnJzogcmV0dXJuIFNxdW90ZTsKICAgIGNhc2UgJyInOiAgcmV0dXJuIERxdW90ZTsKICAgIGNhc2UgJ1xcJzogcmV0dXJuIEJzbGFzaDsKICAgIGNhc2UgJ1xuJzogcmV0dXJuIE5ld2xpbmU7CiAgICBkZWZhdWx0OiAgIHJldHVybiBMZXR0ZXI7CiAgfQp9Cgp2b2lkIGVtaXQgICAgKGludCBjKSB7IHB1dGNoYXIoYyk7IH0Kdm9pZCBzbGFzaCAgIChpbnQgYykgeyBwdXRjaGFyKCcvJyk7IHB1dGNoYXIoYyk7IH0Kdm9pZCBub3RoaW5nIChpbnQgYykgeyB9CnZvaWQgaGFsdCAgICAoaW50IGMpIHsgZXhpdChFWElUX1NVQ0NFU1MpOyB9CgojZGVmaW5lIFQoc3RhdGUsIHNpZ2lsKSAoKChzdGF0ZSkgPDwgNCkgfCBzaWdpbCkKCmludCBtYWluKCkgewogIHRyYW5zaXRpb24gc3RhdGUgPSB7IDAsIGVtaXQgfTsKICB0cmFuc2l0aW9uIHRhYmxlW10gPSB7CgogICAgW1QoMCwgU2xhc2gpXSA9ICAgICB7IDEsIG5vdGhpbmcgfSwKICAgIFtUKDAsIExldHRlcildID0gICAgeyAwLCBlbWl0IH0sCiAgICBbVCgwLCBTdGFyKV0gPSAgICAgIHsgMCwgZW1pdCB9LAogICAgW1QoMCwgRW5kT2ZGaWxlKV0gPSB7IDAsIGhhbHQgfSwKICAgIFtUKDAsIFNxdW90ZSldID0gICAgeyA2LCBlbWl0IH0sCiAgICBbVCgwLCBEcXVvdGUpXSA9ICAgIHsgNCwgZW1pdCB9LAogICAgW1QoMCwgQnNsYXNoKV0gPSAgICB7IDAsIGVtaXQgfSwKICAgIFtUKDAsIE5ld2xpbmUpXSA9ICAgeyAwLCBlbWl0IH0sIC8vIEhhbmRsZSBuZXdsaW5lIGluIHN0YXRlIDAKCiAgICBbVCgxLCBTbGFzaCldID0gICAgIHsgOSwgbm90aGluZyB9LCAgICAvLyBUcmFuc2l0aW9uIHRvIGxpbmUgY29tbWVudCBzdGF0ZQogICAgW1QoMSwgU3RhcildID0gICAgICB7IDIsIG5vdGhpbmcgfSwgICAgLy8gU3RhcnQgb2YgYmxvY2sgY29tbWVudAogICAgW1QoMSwgTGV0dGVyKV0gPSAgICB7IDAsIHNsYXNoIH0sICAgICAgLy8gTm90IGEgY29tbWVudCwgZW1pdCAnLycKICAgIFtUKDEsIEVuZE9mRmlsZSldID0geyAwLCBoYWx0IH0sCiAgICBbVCgxLCBTcXVvdGUpXSA9ICAgIHsgMCwgc2xhc2ggfSwKICAgIFtUKDEsIERxdW90ZSldID0gICAgeyAwLCBzbGFzaCB9LAogICAgW1QoMSwgQnNsYXNoKV0gPSAgICB7IDAsIHNsYXNoIH0sCiAgICBbVCgxLCBOZXdsaW5lKV0gPSAgIHsgMCwgc2xhc2ggfSwgICAgICAvLyBOb3QgYSBjb21tZW50LCBlbWl0ICcvJwoKICAgIFtUKDIsIFNsYXNoKV0gPSAgICAgeyAyLCBub3RoaW5nIH0sCiAgICBbVCgyLCBMZXR0ZXIpXSA9ICAgIHsgMiwgbm90aGluZyB9LAogICAgW1QoMiwgU3RhcildID0gICAgICB7IDMsIG5vdGhpbmcgfSwKICAgIFtUKDIsIEVuZE9mRmlsZSldID0geyAwLCBoYWx0IH0sCiAgICBbVCgyLCBTcXVvdGUpXSA9ICAgIHsgMiwgbm90aGluZyB9LAogICAgW1QoMiwgRHF1b3RlKV0gPSAgICB7IDIsIG5vdGhpbmcgfSwKICAgIFtUKDIsIEJzbGFzaCldID0gICAgeyAyLCBub3RoaW5nIH0sCiAgICBbVCgyLCBOZXdsaW5lKV0gPSAgIHsgMiwgbm90aGluZyB9LCAgICAvLyBOZXdsaW5lcyBpbnNpZGUgYmxvY2sgY29tbWVudHMgYXJlIGlnbm9yZWQKCiAgICBbVCgzLCBTbGFzaCldID0gICAgIHsgMCwgbm90aGluZyB9LAogICAgW1QoMywgTGV0dGVyKV0gPSAgICB7IDIsIG5vdGhpbmcgfSwKICAgIFtUKDMsIFN0YXIpXSA9ICAgICAgeyAyLCBub3RoaW5nIH0sCiAgICBbVCgzLCBFbmRPZkZpbGUpXSA9IHsgMCwgaGFsdCB9LAogICAgW1QoMywgU3F1b3RlKV0gPSAgICB7IDIsIG5vdGhpbmcgfSwKICAgIFtUKDMsIERxdW90ZSldID0gICAgeyAyLCBub3RoaW5nIH0sCiAgICBbVCgzLCBCc2xhc2gpXSA9ICAgIHsgMiwgbm90aGluZyB9LAogICAgW1QoMywgTmV3bGluZSldID0gICB7IDIsIG5vdGhpbmcgfSwKCiAgICBbVCg0LCBTbGFzaCldID0gICAgIHsgNCwgZW1pdCB9LAogICAgW1QoNCwgTGV0dGVyKV0gPSAgICB7IDQsIGVtaXQgfSwKICAgIFtUKDQsIFN0YXIpXSA9ICAgICAgeyA0LCBlbWl0IH0sCiAgICBbVCg0LCBFbmRPZkZpbGUpXSA9IHsgMCwgaGFsdCB9LAogICAgW1QoNCwgU3F1b3RlKV0gPSAgICB7IDQsIGVtaXQgfSwKICAgIFtUKDQsIERxdW90ZSldID0gICAgeyAwLCBlbWl0IH0sCiAgICBbVCg0LCBCc2xhc2gpXSA9ICAgIHsgNSwgZW1pdCB9LAogICAgW1QoNCwgTmV3bGluZSldID0gICB7IDQsIGVtaXQgfSwKCiAgICBbVCg1LCBTbGFzaCldID0gICAgIHsgNCwgZW1pdCB9LAogICAgW1QoNSwgTGV0dGVyKV0gPSAgICB7IDQsIGVtaXQgfSwKICAgIFtUKDUsIFN0YXIpXSA9ICAgICAgeyA0LCBlbWl0IH0sCiAgICBbVCg1LCBFbmRPZkZpbGUpXSA9IHsgMCwgaGFsdCB9LAogICAgW1QoNSwgU3F1b3RlKV0gPSAgICB7IDQsIGVtaXQgfSwKICAgIFtUKDUsIERxdW90ZSldID0gICAgeyA0LCBlbWl0IH0sCiAgICBbVCg1LCBCc2xhc2gpXSA9ICAgIHsgNCwgZW1pdCB9LAogICAgW1QoNSwgTmV3bGluZSldID0gICB7IDQsIGVtaXQgfSwKCiAgICBbVCg2LCBTbGFzaCldID0gICAgIHsgOCwgZW1pdCB9LAogICAgW1QoNiwgTGV0dGVyKV0gPSAgICB7IDgsIGVtaXQgfSwKICAgIFtUKDYsIFN0YXIpXSA9ICAgICAgeyA4LCBlbWl0IH0sCiAgICBbVCg2LCBFbmRPZkZpbGUpXSA9IHsgMCwgaGFsdCB9LAogICAgW1QoNiwgU3F1b3RlKV0gPSAgICB7IDgsIGVtaXQgfSwKICAgIFtUKDYsIERxdW90ZSldID0gICAgeyA4LCBlbWl0IH0sCiAgICBbVCg2LCBCc2xhc2gpXSA9ICAgIHsgNywgZW1pdCB9LAogICAgW1QoNiwgTmV3bGluZSldID0gICB7IDgsIGVtaXQgfSwKCiAgICBbVCg3LCBTbGFzaCldID0gICAgIHsgOCwgZW1pdCB9LAogICAgW1QoNywgTGV0dGVyKV0gPSAgICB7IDgsIGVtaXQgfSwKICAgIFtUKDcsIFN0YXIpXSA9ICAgICAgeyA4LCBlbWl0IH0sCiAgICBbVCg3LCBFbmRPZkZpbGUpXSA9IHsgOCwgZW1pdCB9LAogICAgW1QoNywgU3F1b3RlKV0gPSAgICB7IDgsIGVtaXQgfSwKICAgIFtUKDcsIERxdW90ZSldID0gICAgeyA4LCBlbWl0IH0sCiAgICBbVCg3LCBCc2xhc2gpXSA9ICAgIHsgOCwgZW1pdCB9LAogICAgW1QoNywgTmV3bGluZSldID0gICB7IDgsIGVtaXQgfSwKCiAgICBbVCg4LCBTbGFzaCldID0gICAgIHsgMCwgZW1pdCB9LAogICAgW1QoOCwgTGV0dGVyKV0gPSAgICB7IDAsIGVtaXQgfSwKICAgIFtUKDgsIFN0YXIpXSA9ICAgICAgeyAwLCBlbWl0IH0sCiAgICBbVCg4LCBFbmRPZkZpbGUpXSA9IHsgMCwgaGFsdCB9LAogICAgW1QoOCwgU3F1b3RlKV0gPSAgICB7IDAsIGVtaXQgfSwKICAgIFtUKDgsIERxdW90ZSldID0gICAgeyAwLCBlbWl0IH0sCiAgICBbVCg4LCBCc2xhc2gpXSA9ICAgIHsgMCwgZW1pdCB9LAogICAgW1QoOCwgTmV3bGluZSldID0gICB7IDAsIGVtaXQgfSwKCiAgICAvLyBOZXcgU3RhdGUgOTogSW5zaWRlIExpbmUgQ29tbWVudAogICAgW1QoOSwgU2xhc2gpXSA9ICAgICB7IDksIG5vdGhpbmcgfSwKICAgIFtUKDksIFN0YXIpXSA9ICAgICAgeyA5LCBub3RoaW5nIH0sCiAgICBbVCg5LCBMZXR0ZXIpXSA9ICAgIHsgOSwgbm90aGluZyB9LAogICAgW1QoOSwgU3F1b3RlKV0gPSAgICB7IDksIG5vdGhpbmcgfSwKICAgIFtUKDksIERxdW90ZSldID0gICAgeyA5LCBub3RoaW5nIH0sCiAgICBbVCg5LCBCc2xhc2gpXSA9ICAgIHsgOSwgbm90aGluZyB9LAogICAgW1QoOSwgTmV3bGluZSldID0gICB7IDAsIGVtaXQgfSwgICAgICAgLy8gRW5kIG9mIGxpbmUgY29tbWVudAogICAgW1QoOSwgRW5kT2ZGaWxlKV0gPSB7IDAsIGhhbHQgfSwgICAgICAgLy8gRW5kIG9mIGZpbGUgd2hpbGUgaW4gbGluZSBjb21tZW50CiAgfTsKCiAgZm9yICg7OykgewogICAgaW50IGMgPSBnZXRjaGFyKCk7CiAgICBzdGF0ZSA9IHRhYmxlW1Qoc3RhdGUuc3RhdGUsIHNpZ2lsaWZ5KGMpKV07CiAgICBzdGF0ZS5lZmZlY3QoYyk7CiAgfQp9