DelFusa Blog 総本山

プログラミングの話題とかです。

NEW | PAGE-SELECT | NEXT

≫ EDIT

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

| スポンサー広告 | --:-- | comments(-) | trackbacks(-) | TOP↑

≫ EDIT

ソースからコメントを抜き出したりとか


   ∧,,∧
  ミ,,゚Д゚彡
  ,ミ'  ミ
~OUUつ

まあ、そういいつつも。仕事があるので平穏無事でやっておりますよと。

で、ちょっと前にやっていたDelphiやC++系やVBから
コメントを削除したり、逆にコメントだけを残したりするソースを作りきって
おきました。


どぞ。



そのうち、OpenSource側にも反映させたいです。

テストコードだけみてると、記号の羅列っぽいけど、このテストコードが要なんだな~


unit SourceComment;

interface

uses
StringUnit,
ConstUnit,
uses_end;

function PascalCommentDelete(S: WideString): WideString;
function CCommentDelete(S: WideString): WideString;
function CppCommentDelete(S: WideString): WideString;
function VBCommentDelete(S: WideString): WideString;

function PascalCommentExtraction(S: WideString): WideString;
function CCommentExtraction(S: WideString): WideString;
function CppCommentExtraction(S: WideString): WideString;
function VBCommentExtraction(S: WideString): WideString;

implementation

const
EndOfLine = #13;

type
TSourceStatus = (ssSource, ssComment);

type
TBraceInfo = record
BeginMark: WideString;
EndMark: WideString;
SourceStatus: TSourceStatus
end;

type
TBraceTable = array of TBraceInfo;

function FindCommentStart(const str: WideString; FromIndex: Integer;
BraceTable: TBraceTable;
out SearchIndex: integer; out braceInfo: TBraceInfo ): boolean;
var
bt: Integer;
i: integer;
begin
SearchIndex := MaxInt;
for bt := Low(BraceTable) to High(BraceTable) do
begin
i := RangeWidePosForward( braceTable[bt].BeginMark, str , FromIndex);
if (0 < i) and (i < SearchIndex) then
begin
braceInfo := BraceTable[bt];
SearchIndex := i;
end;
end;
Result := False;
if SearchIndex < MaxInt then
Result := True;
end;

procedure ResultWrite(StartIndex, EndIndex: Integer;
var ResultIndex, SourceIndex: Integer;
var Dest, Source: WideString);
var
i: Integer;
begin
for i := StartIndex to EndIndex do
begin
Dest[ResultIndex] := Source[SourceIndex];
Inc(ResultIndex); Inc(SourceIndex);
end;
end;

function CommentDelete(Source: WideString; BraceTable: TBraceTable): WideString;
var
SearchIndex, i, LoopCount: integer;
removeLen: integer;
bi: TBraceInfo;
SourceIndex, ResultIndex: Integer;
begin
SetLength(Result, Length(Source));
SourceIndex := 1; ResultIndex := 1;
while FindCommentStart(Source, SourceIndex, BraceTable, SearchIndex, bi) do
begin
if bi.SourceStatus = ssSource then
begin

ResultWrite(SourceIndex, SearchIndex + Length(bi.BeginMark) - 1,
ResultIndex, SourceIndex, Result, Source);

if bi.EndMark = '' then Continue;
SearchIndex :=
RangeWidePosForward(bi.EndMark, Source,
SourceIndex);
if SearchIndex = 0 then
begin
ResultWrite(SourceIndex, Length(Source),
ResultIndex, SourceIndex, Result, Source);
SetLength(Result, ResultIndex - 1);
Exit;
end else
begin
ResultWrite(SourceIndex, SearchIndex + Length(bi.EndMark) - 1,
ResultIndex, SourceIndex, Result, Source);
end;

end else
begin

ResultWrite(SourceIndex, SearchIndex - 1,
ResultIndex, SourceIndex, Result, Source);

SourceIndex := SearchIndex + Length(bi.BeginMark);
if bi.EndMark = '' then Continue;

SearchIndex :=
RangeWidePosForward(bi.EndMark, Source,
SourceIndex);
if SearchIndex = 0 then
begin
SetLength(Result, ResultIndex - 1);
Exit;
end else
begin
if bi.EndMark = EndOfLine then
SourceIndex := SearchIndex
else
SourceIndex := SearchIndex + Length(bi.EndMark);
end;
end;
end;

ResultWrite(SourceIndex, Length(Source),
ResultIndex, SourceIndex, Result, Source);
SetLength(Result, ResultIndex-1);
end;

function CommentExtraction(Source: WideString; BraceTable: TBraceTable): WideString;
var
SearchIndex, i, LoopCount: integer;
removeLen: integer;
bi: TBraceInfo;
SourceIndex, ResultIndex: Integer;

begin
SetLength(Result, Length(Source));
SourceIndex := 1; ResultIndex := 1;
while FindCommentStart(Source, SourceIndex, BraceTable, SearchIndex, bi) do
begin
if bi.SourceStatus = ssSource then
begin

SourceIndex := SearchIndex + Length(bi.BeginMark);
SearchIndex :=
RangeWidePosForward(bi.EndMark, Source,
SourceIndex);
if SearchIndex = 0 then
begin
SetLength(Result, ResultIndex - 1);
Exit;
end else
begin
SourceIndex := SearchIndex + Length(bi.EndMark);
Continue;
end;
end else
begin

SourceIndex := SearchIndex;

SearchIndex :=
RangeWidePosForward(bi.EndMark, Source,
SourceIndex + Length(bi.BeginMark));
if SearchIndex = 0 then
begin
ResultWrite(SourceIndex, Length(Source),
ResultIndex, SourceIndex, Result, Source);
SetLength(Result, ResultIndex - 1);
Exit;
end else
begin
ResultWrite(SourceIndex, SearchIndex + Length(bi.EndMark) - 1,
ResultIndex, SourceIndex, Result, Source);
end;
end;
end;

SetLength(Result, ResultIndex-1);
end;

function PascalCommentDelete(S: WideString): WideString;

var
braceTable: TBraceTable;
begin
SetLength(braceTable, 5);
with braceTable[0] do
begin BeginMark := ''''; EndMark := ''''; SourceStatus := ssSource; end;
with braceTable[1] do
begin BeginMark := '{$'; EndMark := '}'; SourceStatus := ssSource; end;
with braceTable[2] do
begin BeginMark := '{'; EndMark := '}'; SourceStatus := ssComment; end;
with braceTable[3] do
begin BeginMark := '(*'; EndMark := '*)'; SourceStatus := ssComment; end;
with braceTable[4] do
begin BeginMark := '//'; EndMark := EndOfLine; SourceStatus := ssComment; end;

Result := CommentDelete(S, braceTable);
end;

function PascalCommentExtraction(S: WideString): WideString;
var
braceTable: TBraceTable;
begin
SetLength(braceTable, 6);
with braceTable[0] do
begin BeginMark := ''''; EndMark := ''''; SourceStatus := ssSource; end;
with braceTable[1] do
begin BeginMark := '{$'; EndMark := '}'; SourceStatus := ssSource; end;
with braceTable[2] do
begin BeginMark := CR; EndMark := LF; SourceStatus := ssComment; end;
with braceTable[3] do
begin BeginMark := '{'; EndMark := '}'; SourceStatus := ssComment; end;
with braceTable[4] do
begin BeginMark := '(*'; EndMark := '*)'; SourceStatus := ssComment; end;
with braceTable[5] do
begin BeginMark := '//'; EndMark := EndOfLine; SourceStatus := ssComment; end;

Result := CommentExtraction(S, braceTable);
end;

function CCommentDelete(S: WideString): WideString;

var
braceTable: TBraceTable;
begin
SetLength(braceTable, 3);
with braceTable[0] do
begin BeginMark := '\"'; EndMark := ''; SourceStatus := ssSource; end;
with braceTable[1] do
begin BeginMark := '"'; EndMark := '"'; SourceStatus := ssSource; end;
with braceTable[2] do
begin BeginMark := '/*'; EndMark := '*/'; SourceStatus := ssComment; end;

Result := CommentDelete(S, braceTable);
end;

function CCommentExtraction(S: WideString): WideString;
var
braceTable: TBraceTable;
begin
SetLength(braceTable, 4);
with braceTable[0] do
begin BeginMark := '\"'; EndMark := ''; SourceStatus := ssSource; end;
with braceTable[1] do
begin BeginMark := '"'; EndMark := '"'; SourceStatus := ssSource; end;
with braceTable[2] do
begin BeginMark := CR; EndMark := LF; SourceStatus := ssComment; end;
with braceTable[3] do
begin BeginMark := '/*'; EndMark := '*/'; SourceStatus := ssComment; end;

Result := CommentExtraction(S, braceTable);
end;

function CppCommentDelete(S: WideString): WideString;

var
braceTable: TBraceTable;
begin
SetLength(braceTable, 4);
with braceTable[0] do
begin BeginMark := '\"'; EndMark := ''; SourceStatus := ssSource; end;
with braceTable[1] do
begin BeginMark := '"'; EndMark := '"'; SourceStatus := ssSource; end;
with braceTable[2] do
begin BeginMark := '/*'; EndMark := '*/'; SourceStatus := ssComment; end;
with braceTable[3] do
begin BeginMark := '//'; EndMark := EndOfLine; SourceStatus := ssComment; end;

Result := CommentDelete(S, braceTable);
end;

function CppCommentExtraction(S: WideString): WideString;
var
braceTable: TBraceTable;
begin
SetLength(braceTable, 5);
with braceTable[0] do
begin BeginMark := '\"'; EndMark := ''; SourceStatus := ssSource; end;
with braceTable[1] do
begin BeginMark := '"'; EndMark := '"'; SourceStatus := ssSource; end;
with braceTable[2] do
begin BeginMark := CR; EndMark := LF; SourceStatus := ssComment; end;
with braceTable[3] do
begin BeginMark := '/*'; EndMark := '*/'; SourceStatus := ssComment; end;
with braceTable[4] do
begin BeginMark := '//'; EndMark := EndOfLine; SourceStatus := ssComment; end;

Result := CommentExtraction(S, braceTable);
end;

function VBCommentDelete(S: WideString): WideString;

var
braceTable: TBraceTable;
begin
SetLength(braceTable, 2);
with braceTable[0] do
begin beginMark := '"'; endmark := '"'; SourceStatus := ssSource; end;
with braceTable[1] do
begin beginMark := ''''; endmark := EndOfLine; SourceStatus := ssComment; end;

Result := CommentDelete(S, braceTable);
end;

function VBCommentExtraction(S: WideString): WideString;
var
braceTable: TBraceTable;
begin
SetLength(braceTable, 3);
with braceTable[0] do
begin beginMark := '"'; endmark := '"'; SourceStatus := ssSource; end;
with braceTable[1] do
begin BeginMark := CR; EndMark := LF; SourceStatus := ssComment; end;
with braceTable[2] do
begin beginMark := ''''; endmark := EndOfLine; SourceStatus := ssComment; end;

Result := CommentExtraction(S, braceTable);
end;

end.

────────────────────

unit testSourceComment;

interface

uses
SysUtils,
SourceComment,
XPtest,
uses_end;

procedure testPascalCommentDelete;
procedure testCppCommentDelete;
procedure testPascalCommentExtraction;

implementation

procedure testPascalCommentDelete;
begin
Check('あいうえおさしすせそ', PascalCommentDelete('あいうえお{かきくけこ}さしすせそ'));
Check('あいうえおさしすせそ', PascalCommentDelete('あいうえお(*かきくけこ*)さしすせそ'));
Check('あいうえお'#13#10#13#10'さしすせそ',
PascalCommentDelete('あいうえお'#13#10'//かきくけこ'#13#10'さしすせそ'));

Check('かきくけこさしすせそ', PascalCommentDelete('{あいうえお}かきくけこさしすせそ'));
Check('かきくけこさしすせそ', PascalCommentDelete('(*あいうえお*)かきくけこさしすせそ'));
Check(#13#10'かきくけこ'#13#10'さしすせそ',
PascalCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'さしすせそ'));

Check('あいうえおかきくけこ', PascalCommentDelete('あいうえおかきくけこ{さしすせそ}'));
Check('あいうえおかきくけこ', PascalCommentDelete('あいうえおかきくけこ(*さしすせそ*)'));
Check('あいうえお'#13#10'かきくけこ'#13#10,
PascalCommentDelete('あいうえお'#13#10'かきくけこ'#13#10'//さしすせそ'));

Check('かきくけこ', PascalCommentDelete('{あいうえお}かきくけこ(*さしすせそ*)'));
Check('かきくけこ', PascalCommentDelete('(*あいうえお*)かきくけこ{さしすせそ}'));
Check(#13#10'かきくけこ'#13#10,
PascalCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'{さしすせそ}'));

Check('あい''{うえ(*''お*)', PascalCommentDelete('あい''{うえ(*''お{かき''くけこ}*)'));

Check('かきくけこ', PascalCommentDelete('{あいうえお}かきくけこ(*さしすせそ'));
Check('かきくけこ', PascalCommentDelete('(*あいうえお*)かきくけこ{さしすせそ'));
Check(#13#10'かきくけこ'#13#10,
PascalCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'{さしすせそ'));

Check('あいうえお}かきくけこ', PascalCommentDelete('あいうえお}かきくけこ(*さしすせそ'));
Check('あいうえお*)かきくけこ', PascalCommentDelete('あいうえお*)かきくけこ{さしすせそ'));
Check('あい'#13#10'かきくけこ'#13#10,
PascalCommentDelete('あい//うえお'#13#10'かきくけこ'#13#10'{さしすせそ'));

Check('さしすせそ*)', PascalCommentDelete('(*あいうえお(*かきくけこ*)さしすせそ*)'));


Check('あいうえお{$かきくけこ}さしすせそ', PascalCommentDelete('あいうえお{$かきくけこ}さしすせそ'));

Check('{$あいうえお}かきくけこさしすせそ', PascalCommentDelete('{$あいうえお}かきくけこさしすせそ'));

Check('あいうえおかきくけこ{$さしすせそ}', PascalCommentDelete('あいうえおかきくけこ{$さしすせそ}'));

Check('{$あいうえお}かきくけこ', PascalCommentDelete('{$あいうえお}かきくけこ(*さしすせそ*)'));
Check('かきくけこ{$さしすせそ}', PascalCommentDelete('(*あいうえお*)かきくけこ{$さしすせそ}'));
Check(#13#10'かきくけこ'#13#10'{$さしすせそ}',
PascalCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'{$さしすせそ}'));

Check('あい''{$うえ(*''お{$かき''くけこ}*)', PascalCommentDelete('あい''{$うえ(*''お{$かき''くけこ}*)'));
Check('abc''''def', PascalCommentDelete('abc''''d{123}ef'));
Check('abc''''def', PascalCommentDelete('abc''''d(*123*)ef'));
Check('abc''''d'#13#10'ef', PascalCommentDelete('abc''''d//123'#13#10'ef'));

Check('{$あいうえお}かきくけこ', PascalCommentDelete('{$あいうえお}かきくけこ(*さしすせそ'));
Check('かきくけこ{$さしすせそ', PascalCommentDelete('(*あいうえお*)かきくけこ{$さしすせそ'));
Check(#13#10'かきくけこ'#13#10'{$さしすせそ',
PascalCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'{$さしすせそ'));

Check('あいうえお*)かきくけこ{$さしすせそ', PascalCommentDelete('あいうえお*)かきくけこ{$さしすせそ'));
Check('あい'#13#10'かきくけこ'#13#10'{$さしすせそ',
PascalCommentDelete('あい//うえお'#13#10'かきくけこ'#13#10'{$さしすせそ'));


Check('あいうえお', PascalCommentDelete('あいうえお(**)(**)(*)abc*)'));
Check('あいうえお', PascalCommentDelete('あいうえお(**)(**)(*)abc'));
Check('あいうえお', PascalCommentDelete('あいうえ(**)(**)(*)abc*)お'));
Check('あいうえ''(*)abc*)''お', PascalCommentDelete('あいうえ(**)(**)''(*)abc*)''お'));
Check('あいうえ''(*)abc*)''', PascalCommentDelete('あいうえ(**)(**)''(*)abc*)''//お'));
Check('あいうえ''(*)abc*)お', PascalCommentDelete('あいうえ(**)(**)''(*)abc*)お'));
end;

procedure testPascalCommentExtraction;
begin
Check('{かきくけこ}', PascalCommentExtraction('あいうえお{かきくけこ}さしすせそ'));
Check('{かきくけこ}', PascalCommentExtraction('あい''''うえお{かきくけこ}さし''''すせそ'));
Check('', PascalCommentExtraction('あい''うえお{かきくけこ}さし''すせそ'));
Check('{かきくけこ}', PascalCommentExtraction(
StringReplace('あい""うえお{かきくけこ}さし""すせそ', '"', '''', [rfReplaceAll])));
Check('', PascalCommentExtraction(
StringReplace('あい"うえお{かきくけこ}さし"すせそ', '"', '''', [rfReplaceAll])));
end;

procedure testCppCommentDelete;
begin
Check('あいうえおさしすせそ', CppCommentDelete('あいうえお/*かきくけこ*/さしすせそ'));
Check('あいうえお'#13#10#13#10'さしすせそ',
CppCommentDelete('あいうえお'#13#10'//かきくけこ'#13#10'さしすせそ'));

Check('かきくけこさしすせそ', CppCommentDelete('/*あいうえお*/かきくけこさしすせそ'));
Check(#13#10'かきくけこ'#13#10'さしすせそ',
CppCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'さしすせそ'));

Check('あいうえおかきくけこ', CppCommentDelete('あいうえおかきくけこ/*さしすせそ*/'));
Check('あいうえお'#13#10'かきくけこ'#13#10,
CppCommentDelete('あいうえお'#13#10'かきくけこ'#13#10'//さしすせそ'));

Check('かきくけこ', CppCommentDelete('/*あいうえお*/かきくけこ/*さしすせそ*/'));
Check(#13#10'かきくけこ'#13#10,
CppCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'/*さしすせそ*/'));

Check('あい"/*うえ/*"お*/', CppCommentDelete('あい"/*うえ/*"お/*かき"くけこ*/*/'));


Check('かきくけこ', CppCommentDelete('/*あいうえお*/かきくけこ/*さしすせそ'));
Check(#13#10'かきくけこ'#13#10,
CppCommentDelete('//あいうえお'#13#10'かきくけこ'#13#10'/*さしすせそ'));

Check('あいうえお*/かきくけこ', CppCommentDelete('あいうえお*/かきくけこ/*さしすせそ'));
Check('あい'#13#10'かきくけこ'#13#10,
CppCommentDelete('あい//うえお'#13#10'かきくけこ'#13#10'/*さしすせそ'));

Check('さしすせそ*/', CppCommentDelete('/*あいうえお/*かきくけこ*/さしすせそ*/'));

Check('あいうえお', CppCommentDelete('あいうえお/**//**//*/abc*/'));
Check('あいうえお', CppCommentDelete('あいうえお/**//**//*/abc'));
Check('あいうえお', CppCommentDelete('あいうえ/**//**//*/abc*/お'));


Check(' fprintf(fout, "%s/*", tag_com);', CCommentDelete(' fprintf(fout, "%s/*", tag_com);'));
Check(' fprintf(fout, "%s/*", tag_com);', CppCommentDelete(' fprintf(fout, "%s/*", tag_com);'));

Check('case ''\"'': fputs(""", fout); break;',
CppCommentDelete('case ''\"'': fputs(""", fout); break;/*aa*/'));

end;

end.


さて、このコードを使ってEmEditorPluginをつくってます。
エディタで、ワンクリックでこの機能が使えたら、便利です。

もちろん、C/C++/Java/C#/VB使い、いずれにも便利なわけです。

動作している画像はこんな感じ

pascalsource
commentdelete
sourcedelete

スポンサーサイト

| 未分類 | 01:53 | comments:5 | trackbacks(-) | TOP↑

COMMENT

No title

そうそう。ブログ掲載時にインデントを全角スペースにしたりしているけど、これもプラグインでインデント部分だけ全角⇔半角スペース変換かけているから、操作がとても楽だよ。

| ミ・д・彡 | 2008/12/01 02:14 | URL | ≫ EDIT

画像枚数増やしました

動作がよくわかるように、画像の枚数を増やしたよ。オープンソース、するときに余計なヘッダとかを削除すると、なんかいろんな思考過程とかプライベートなコメントが削除されて、いい気分でソースを公開できます。

ソース。よかったら利用ください。

| ミ・д・彡 | 2008/12/01 21:25 | URL | ≫ EDIT

気になったので

<pre>
// ソース見本
procedure ResultWrite(StartIndex, EndIndex: Integer;
var ResultIndex, SourceIndex: Integer;
var Dest, Source: WideString);
var
i: Integer;
begin
for i := StartIndex to EndIndex do
begin
Dest[ResultIndex] := Source[SourceIndex];
Inc(ResultIndex); Inc(SourceIndex);
end;
end;
</pre>

...ソースは上のような感じで <pre>~</pre>で囲んだ方が利用する人にとってはいいのでは?
(上のリストの半角空白はコメントでは省かれるみたいです)

全角空白があると変換が面倒では?

余計なお節介でした~~~ m(__)m

| 通りがかり | 2008/12/02 23:47 | URL | ≫ EDIT

PRE

いえいえ、ありがとうございます。

ついつい、PREは無効なのかなと、思いこんでしまっていました。修正しましたよ。見やすいかな?

| ミ・д・彡 | 2008/12/03 01:44 | URL | ≫ EDIT

自分用メモ

自分用のメモですが、
VBのコメントはREMという文字でもできることがわかりました。

このような行を追加しましょう。
with braceTable[2] do
begin beginMark := 'rem'; endmark := EndOfLine; SourceStatus := ssComment; end;

REMのおかげで検索時に大小文字を無視する検索を考慮するべし。ということで
すこし改良になるかな。


そういえば、HTMLのコメントを除去したり抜き出したりするのは
おそらく、次のコードでいいと思う。

あとで試してみよう。

<PRE>
function HTMLCommentDelete(S: WideString): WideString;
var
braceTable: TBraceTable;
begin
SetLength(braceTable, 1);
with braceTable[0] do
begin beginMark := '<!--'; endmark := '-->'; SourceStatus := ssComment; end;

Result := CommentDelete(S, braceTable);
end;

function HTMLCommentExtraction(S: WideString): WideString;
var
braceTable: TBraceTable;
begin
SetLength(braceTable, 1);
with braceTable[0] do
begin beginMark := '<!--'; endmark := '-->'; SourceStatus := ssComment; end;

Result := CommentExtraction(S, braceTable);
end;
</PRE>

| ミ・д・彡 | 2008/12/09 15:58 | URL | ≫ EDIT















非公開コメント

PREV | PAGE-SELECT | NEXT

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。