お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"HTLM の TABLE タグを解析"

この発言に対し以下のコメントが寄せられています
#00960 DUDE さん RE:HTML の TABLE タグを解析(1)
#00961 DUDE さん RE:HTLM の TABLE タグを解析(2)

Turbo Pascal 用の lex & yacc (もちろん Delphi でも使えます)があること を教えてもらったので、それを使って HTML Parser もどきを書いてみました。 ●Turbo Pascal Lex/Yacc written by Albert Graef http://www.musikwissenschaft.uni-mainz.de/~ag/tply/tply.html ただし、この lex ライブラリはコンソール専用&短い文字列専用にできている ので、GUI アプリケーションで使うためには若干の修正が必要です。 tply41.zip に含まれる LexLib.pas を以下のように変更します。 ・ファイルの先頭に {$H-} を追加。 ・ファイルの末尾を以下のように変更。 {$IFDEF CONSOLE} assign(yyinput, ''); assign(yyoutput, ''); reset(yyinput); rewrite(yyoutput); {$ENDIF} yacc の方はそのまま使えますが、%type で長い文字列が使えないという制限が あります(レコードの可変部に長い文字列が置けないため)。 このサンプルは HTML ファイルを解析して、その中に含まれる TABLE タグを抽 出し、ツリーにして表示するものです。入れ子になった TABLE に対応していな いのと(構文は対応していますが、アクションが対応していません)、文字列の 長さが255文字に制限されます。また、連続して複数の HTML を開く事ができま せん。 Main という名前でフォーム(名前は TForm1)用のユニットを作り、それにボタ ン(TButton; 名前は Button1)1個と、ツリービューコントロール (TTreeView; 名前は TreeView1)1個を置いてください。ボタンのハンドラは ソースにある通りです。その他にはイベントハンドラはありません。 テキストファイルは3つ(token.l、pars.y、main.pas)、フォームファイルが 1つ(main.dfm)、プロジェクトファイルが1つ(htmlp.dpr)の構成です。 同じものをパッケージにまとめたものを http://member.nifty.ne.jp/dude/files/htmlp.lzh にも置いておきました。 ------------------------------------------------------------------------------ <---- token.l ---- %% "<"[Tt][Aa][Bb][Ll][Ee](">"|" "+[^>]*">") return(TABLE); "</"[Tt][Aa][Bb][Ll][Ee](">"|" "+[^>]*">") return(_TABLE); "<"[Tt][Rr](">"|" "+[^>]*">") return(TR); "</"[Tt][Rr](">"|" "+[^>]*">") return(_TR); "<"[Tt][Hh](">"|" "+[^>]*">") return(TH); "</"[Tt][Hh](">"|" "+[^>]*">") return(_TH); "<"[Tt][Dd](">"|" "+[^>]*">") return(TD); "</"[Tt][Dd](">"|" "+[^>]*">") return(_TD); "<!-".*"->" ; /* comment */ [\n\t ]+ begin yylval.yyShortString := yytext; return(SP); end; . begin yylval.yyShortString := yytext; return(CH); end; <---- pars.y ---- /* HTML TABLE tag parser for sample-gura. Written by Yutaka Iizuka(DUDE) */ %{ unit pars; interface uses YaccLib, LexLib, Main; function yyparse : Integer; implementation %} %token TABLE %token _TABLE %token TR %token _TR %token TH %token _TH %token TD %token _TD %token <ShortString> SP %token <ShortString> CH %token ILLEGAL %type <ShortString> string %% s : /* empty */ | s element ; element : table | string { if Assigned(CurrentCell) then begin Form1.TreeView1.Items.AddChild(CurrentCell, $1); end; } ; table : table_begin table_rows table_end ; table_begin : TABLE { CurrentTable := Form1.TreeView1.Items.AddChild(CurrentCell, 'TABLE'); } ; table_end : _TABLE { CurrentTable := nil; } ; table_rows : /* empty */ | table_rows table_row ; table_row : tr_begin table_data_list tr_end | SP ; tr_begin : TR { if Assigned(CurrentTable) then begin CurrentRow := Form1.TreeView1.Items.AddChild(CurrentTable, 'TR'); end; } ; tr_end : _TR { CurrentRow := nil; } | /* empty */ { CurrentRow := nil; } ; table_data_list : /* empty */ | table_data_list table_data ; table_data : th_begin element th_end | td_begin element td_end | SP ; th_begin : TH { if Assigned(CurrentRow) then begin CurrentCell := Form1.TreeView1.Items.AddChild(CurrentRow, 'TH'); end; } ; th_end : _TH { CurrentCell := nil; } ; td_begin : TD { if Assigned(CurrentRow) then begin CurrentCell := Form1.TreeView1.Items.AddChild(CurrentRow, 'TD'); end; } ; td_end : _TD { CurrentCell := nil; } ; string : /* empty */ { $$ := ''; } | string CH { $$ := $1 + $2; } | string SP { $$ := $1 + $2; } ; %% {$I token.pas} begin end. <---- main.pas ---- unit Main; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Panel1: TPanel; Button1: TButton; TreeView1: TTreeView; procedure Button1Click(Sender: TObject); end; var Form1: TForm1; CurrentTable:TTreeNode; CurrentRow:TTreeNode; CurrentCell:TTreeNode; implementation {$R *.DFM} uses Pars, LexLib, YaccLib; procedure TForm1.Button1Click(Sender: TObject); begin with TOpenDialog.Create(Self) do begin Options := [ofHideReadOnly]; Filter := 'HTML Files|*.html;*.htm|Text Files|*.txt'; if Execute then begin CurrentTable := nil; CurrentRow := nil; CurrentCell := nil; AssignFile(yyinput, FileName); Reset(yyinput); yyparse; TreeView1.Items.BeginUpdate; try TreeView1.FullExpand; finally TreeView1.Items.EndUpdate; end; end; end; end; end. 99/10/4(Mon) 08:45pm [AirCraft開発] PFF01344 DUDE http://member.nifty.ne.jp/dude/ Original document by DUDE 氏 ID:(PFF01344)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum