Javaのコメント
https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.7
/* text */
// text
flexを使ってコメントを削除する
flexをインストールする
$ sudo yum install flex $ sudo yum install flex-devel
(delete_java_comments.l)
%x COMMENT %% "/*" { BEGIN(COMMENT); } <COMMENT>"*/" { BEGIN(INITIAL); } <COMMENT>.|\n "//".*\n { printf("\n"); } .|\n { printf("%s",yytext); } %% main(int argc, char **argv){ yylex(); }
コンパイルする
$ flex delete_java_comments.l $ cc lex.yy.c -lfl
実行してみる
$ cat test.txt /* aaa */ aaa bbb // ccc /* aaa */ ccc // ddd aaa bbb /* ccc */ aaa /* // bbb */ aaa // bbb /* ccc */ $ ./a.out < test.txt aaa bbb ccc aaa bbb aaa aaa
・dot doesn't match a newline
https://books.google.co.jp/books?id=3Sr1V5J9_qMC&pg=PA31&lpg=PA31&dq=flex+start+state+newline&source=bl&ots=WGGrg9oILN&sig=teAeeXLlk6MDIljpZ0cqtcf0PBI&hl=ja&sa=X&ved=0ahUKEwi55vOq8PXZAhVFxrwKHdpVBYwQ6AEIUzAD#v=onepage&q=flex%20start%20state%20newline&f=false
今まで知らんかった((((;゚Д゚))))
マニュアルに書いてあるわ
$ man flex .. パターン 入力ファイルのパターンは拡張した正規表現を使って記述します。 以下に示します: x 文字 'x' にマッチ。 . 改行を除く全ての文字(バイト)。 ..
・BEGIN(INITIAL) in flex parser
https://stackoverflow.com/questions/22527608/begininitial-in-flex-parser
PLY (Python Lex-Yacc)を使ってコメントを削除する
http://www.dabeaz.com/ply/ply.html
(delete_java_comments.py)
#!/usr/bin/env python import sys import ply.lex as lex tokens = ( 'ANY', ) def t_comment(t): r'(/\*(.|\n)*?\*/)|(//.*)' pass def t_ANY(t): r'.|\n' sys.stdout.write("%s" % t.value[0]) def t_error(t): print("Illegal character '%s'" % t.value[0]), t.lexer.skip(1) lexer = lex.lex() data = sys.stdin.read() lexer.input(data) while True: tok = lexer.token() if not tok: break print(tok)
実行してみる
$ cat test.txt /* aaa */ aaa bbb // ccc /* aaa */ ccc // ddd aaa bbb /* ccc */ aaa /* // bbb */ aaa // bbb /* ccc */ $ ./delete_java_comments.py < test.txt aaa bbb ccc aaa bbb aaa aaa
↑たまたまうまく動作したと思われる。
def t_comment(t)とdef t_ANY(t)の順番を逆にしたらコメント削除しない。。
本当は、ちゃんとstart conditionの定義をしないといけないんだろう。
(delete_java_comments_fail.py)
#!/usr/bin/env python import sys import ply.lex as lex tokens = ( 'ANY', ) def t_ANY(t): r'.|\n' sys.stdout.write("%s" % t.value[0]) def t_comment(t): r'(/\*(.|\n)*?\*/)|(//.*)' pass #def t_ANY(t): # r'.|\n' # sys.stdout.write("%s" % t.value[0]) def t_error(t): print("Illegal character '%s'" % t.value[0]), t.lexer.skip(1) lexer = lex.lex() data = sys.stdin.read() lexer.input(data) while True: tok = lexer.token() if not tok: break print(tok)
実行してみる
$ ./delete_java_comments_fail.py < test.txt /* aaa */ aaa bbb // ccc /* aaa */ ccc // ddd aaa bbb /* ccc */ aaa /* // bbb */ aaa // bbb /* ccc */