「プログラム」カテゴリーアーカイブ
DeclVisitorが呼んでくれる関数のリスト
clangのDeclVisitorが呼んでくれる関数のリストがお手軽にほしかったので調べてみました。
以下のコマンドで出力することができます。
# DeclVisitor.hのマクロを参考にいたしました。
1 2 3 4 5 |
$ clang++ --version clang version 4.0.0-1ubuntu1 (tags/RELEASE_400/rc1) Target: i686-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin |
1 2 3 4 5 6 |
$cat Macro \#ifndef RetTy \#define RetTy void \#endif \#define DECL(DERIVED, BASE) virtual RetTy Visit##DERIVED##Decl(const DERIVED##Decl * const D) {} \#include "clang/AST/DeclNodes.inc" |
1 |
$ cat Macro | clang++ -E - -I/usr/lib/llvm-4.0/include | egrep "^[^#$]" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
virtual void VisitAccessSpecDecl(const AccessSpecDecl * const D) {} virtual void VisitBlockDecl(const BlockDecl * const D) {} virtual void VisitCapturedDecl(const CapturedDecl * const D) {} virtual void VisitClassScopeFunctionSpecializationDecl(const ClassScopeFunctionSpecializationDecl * const D) {} virtual void VisitEmptyDecl(const EmptyDecl * const D) {} virtual void VisitExportDecl(const ExportDecl * const D) {} virtual void VisitExternCContextDecl(const ExternCContextDecl * const D) {} virtual void VisitFileScopeAsmDecl(const FileScopeAsmDecl * const D) {} virtual void VisitFriendDecl(const FriendDecl * const D) {} virtual void VisitFriendTemplateDecl(const FriendTemplateDecl * const D) {} virtual void VisitImportDecl(const ImportDecl * const D) {} virtual void VisitLinkageSpecDecl(const LinkageSpecDecl * const D) {} virtual void VisitNamedDecl(const NamedDecl * const D) {} virtual void VisitLabelDecl(const LabelDecl * const D) {} virtual void VisitNamespaceDecl(const NamespaceDecl * const D) {} virtual void VisitNamespaceAliasDecl(const NamespaceAliasDecl * const D) {} virtual void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl * const D) {} virtual void VisitObjCContainerDecl(const ObjCContainerDecl * const D) {} virtual void VisitObjCCategoryDecl(const ObjCCategoryDecl * const D) {} virtual void VisitObjCImplDecl(const ObjCImplDecl * const D) {} virtual void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl * const D) {} virtual void VisitObjCImplementationDecl(const ObjCImplementationDecl * const D) {} virtual void VisitObjCInterfaceDecl(const ObjCInterfaceDecl * const D) {} virtual void VisitObjCProtocolDecl(const ObjCProtocolDecl * const D) {} virtual void VisitObjCMethodDecl(const ObjCMethodDecl * const D) {} virtual void VisitObjCPropertyDecl(const ObjCPropertyDecl * const D) {} virtual void VisitTemplateDecl(const TemplateDecl * const D) {} virtual void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl * const D) {} virtual void VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl * const D) {} virtual void VisitClassTemplateDecl(const ClassTemplateDecl * const D) {} virtual void VisitFunctionTemplateDecl(const FunctionTemplateDecl * const D) {} virtual void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl * const D) {} virtual void VisitVarTemplateDecl(const VarTemplateDecl * const D) {} virtual void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * const D) {} virtual void VisitTypeDecl(const TypeDecl * const D) {} virtual void VisitTagDecl(const TagDecl * const D) {} virtual void VisitEnumDecl(const EnumDecl * const D) {} virtual void VisitRecordDecl(const RecordDecl * const D) {} virtual void VisitCXXRecordDecl(const CXXRecordDecl * const D) {} virtual void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl * const D) {} virtual void VisitClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl * const D) {} virtual void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * const D) {} virtual void VisitTypedefNameDecl(const TypedefNameDecl * const D) {} virtual void VisitObjCTypeParamDecl(const ObjCTypeParamDecl * const D) {} virtual void VisitTypeAliasDecl(const TypeAliasDecl * const D) {} virtual void VisitTypedefDecl(const TypedefDecl * const D) {} virtual void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl * const D) {} virtual void VisitUsingDecl(const UsingDecl * const D) {} virtual void VisitUsingDirectiveDecl(const UsingDirectiveDecl * const D) {} virtual void VisitUsingPackDecl(const UsingPackDecl * const D) {} virtual void VisitUsingShadowDecl(const UsingShadowDecl * const D) {} virtual void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl * const D) {} virtual void VisitValueDecl(const ValueDecl * const D) {} virtual void VisitBindingDecl(const BindingDecl * const D) {} virtual void VisitDeclaratorDecl(const DeclaratorDecl * const D) {} virtual void VisitFieldDecl(const FieldDecl * const D) {} virtual void VisitObjCAtDefsFieldDecl(const ObjCAtDefsFieldDecl * const D) {} virtual void VisitObjCIvarDecl(const ObjCIvarDecl * const D) {} virtual void VisitFunctionDecl(const FunctionDecl * const D) {} virtual void VisitCXXMethodDecl(const CXXMethodDecl * const D) {} virtual void VisitCXXConstructorDecl(const CXXConstructorDecl * const D) {} virtual void VisitCXXConversionDecl(const CXXConversionDecl * const D) {} virtual void VisitCXXDestructorDecl(const CXXDestructorDecl * const D) {} virtual void VisitMSPropertyDecl(const MSPropertyDecl * const D) {} virtual void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * const D) {} virtual void VisitVarDecl(const VarDecl * const D) {} virtual void VisitDecompositionDecl(const DecompositionDecl * const D) {} virtual void VisitImplicitParamDecl(const ImplicitParamDecl * const D) {} virtual void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl * const D) {} virtual void VisitParmVarDecl(const ParmVarDecl * const D) {} virtual void VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl * const D) {} virtual void VisitVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl * const D) {} virtual void VisitEnumConstantDecl(const EnumConstantDecl * const D) {} virtual void VisitIndirectFieldDecl(const IndirectFieldDecl * const D) {} virtual void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl * const D) {} virtual void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl * const D) {} virtual void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl * const D) {} virtual void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl * const D) {} virtual void VisitPragmaCommentDecl(const PragmaCommentDecl * const D) {} virtual void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl * const D) {} virtual void VisitStaticAssertDecl(const StaticAssertDecl * const D) {} virtual void VisitTranslationUnitDecl(const TranslationUnitDecl * const D) {} |
RetTy定義を-Dオプションで与えれば戻り値を変更できます。
1 |
$ cat Macro | clang++ -E - -I/usr/lib/llvm-4.0/include -DRetTy=bool | egrep "^[^#$]" |
1 2 3 4 |
virtual bool VisitAccessSpecDecl(const AccessSpecDecl * const D) {} virtual bool VisitBlockDecl(const BlockDecl * const D) {} virtual bool VisitCapturedDecl(const CapturedDecl * const D) {} : |
gitとPrivateRipository(bitbucket)を作る
- bitbucketでprivate ripositoryを作成しておく
- 作業ディレクトリでcloneする
12345$git clone https://bbbae@bitbucket.org/bbbae/private_repository_name$cd private_repository_name$git remote -vorigin https://bbbae@bitbucket.org/bbbae/private_repository_name (fetch)origin https://bbbae@bitbucket.org/bbbae/private_repository_name (push)
- 作業状態を確認
-
1234567891011$ git statusブランチ masterYour branch is based on 'origin/master', but the upstream is gone.(use "git branch --unset-upstream" to fixup)追跡されていないファイル:(use "git add <file>..." to include in what will be committed)FileManager/nothing added to commit but untracked files present (use "git add" to track)$</file>
- ファイルを追加
-
123456789101112$ git add FileManager$ git statusブランチ masterYour branch is based on 'origin/master', but the upstream is gone.(use "git branch --unset-upstream" to fixup)コミット予定の変更点:(use "git reset HEAD <file>..." to unstage)new file: FileManager/a.outnew file: FileManager/main.cxx$</file>
- 追加ファイルを登録解除
-
12345678910111213141516$ git reset FileManager/a.out$ git statusブランチ masterYour branch is based on 'origin/master', but the upstream is gone.(use "git branch --unset-upstream" to fixup)コミット予定の変更点:(use "git reset HEAD <file>..." to unstage)new file: FileManager/main.cxx追跡されていないファイル:(use "git add </file><file>..." to include in what will be committed)FileManager/a.out$</file>
- 管理外のファイルを削除
-
123456$ git clean -nWould remove FileManager/a.out$ git clean -fRemoving FileManager/a.out$ git clean -n$
- コミット
-
12345678910$ git commit -m "adding FileManager"[master 1f2726d] adding FileManager1 file changed, 20 insertions(+)create mode 100644 FileManager/main.cxx$ git statusブランチ masterYour branch is based on 'origin/master', but the upstream is gone.(use "git branch --unset-upstream" to fixup)nothing to commit, working tree clean$
- プライベートリポジトリへpush
-
12345678910$ git pushPassword for 'https://bbbae@bitbucket.org':Counting objects: 8, done.Delta compression using up to 2 threads.Compressing objects: 100% (5/5), done.Writing objects: 100% (8/8), 887 bytes | 0 bytes/s, done.Total 8 (delta 0), reused 0 (delta 0)To https://bitbucket.org/bbbae/sample_clang* [new branch] master -> master$
Private Ripository
bitbucketには個人のプライベートリポジトリを作成することができる。
技術的な動作確認等でサンプルでソースコードを書くこともあり、少しずつだけれど増えていって結構な量となっていました。たまに「あれってどうだったかな?」と引っ張り出してきて見るわけです。
こういった目的では、やはりローカルで管理するには不便過ぎます。
個人でリポジトリサーバを設ける事も考えられますが、bitbucketの様な無料で多機能なサイトが存在するからには使わない手は無いでしょう。
かくしてどのPCもローカルソースはクローンとなりました。
とっても便利な時代になりましたね。
[Haskell]4つのWord8からWord32に変更する
入力で受け取ったByteStringを32bitの数値で扱いたい。
いろいろ方法がありそうだけど、自前で作成してみた。Cならばunionで4バイト領域にへunsigned charとunsigned longとしてアクセス可能で便利であるが、型が厳密なHaskellではそうはゆかないようです。
ByteStringをWord8のリストで扱うことは容易なので、ByteString -> Word8を4つ切り取って、Word32へ変更という作戦です。
重要なのは「分かっている」ということ
もうずいぶん前から、10年近くはなるんじゃないだろうか。いまに至るまでもずうっと考えていて、文章にはしていなかったこと。「関数プログラミング実践入門」という本にそのまま書いてあった。
…ここでの「分かっている」は「言語機能として処理系の基準で判断できる」ということ…
開発プロセスのノウハウや明らかになった理論をソースコードとの関連を持ったまま作業できる環境とすること。これにより次のことを可能にできる。
…プログラマ自身が人間として限界のある記憶力でいつまで覚えているか、また、手を入れる他のプログラマも同様に分かっているか、は一切保証していません。…プログラマが言語の制約を破ることがそもそもできなければ、誰が処理に手を加えても性質は保証されるのです。
事業継続のために情報が落ちずに引き継がれ、品質が確保しながら作業性を向上する。
…多くの場合、プログラムはメンテナンスなりアップデートしてユーザーに提供しなけれなりません。仕様として正しい動作を定め直し、現実的なコストと時間内で、できればプログラマに過度の負担がかからない範囲で、プログラムに手を入れ続ける…
プロダクトを提供し続けながら、実務者の負担を押さえていくことが可能ということだ。
そう、これがずっと欲しいと思っていたことだ。
問題は明瞭で、ソフトウェアのライフサイクルはある技術者が担当する期間よりも遥かに長く、派生するソフトウェアまで含めてしまえば現役期間よりも長くなる場合が想定されるということ。そのため情報の漏れない伝承と教育が必要。この作業は個人には後ろ向きに捉えられやすく、後回しになりやすいということ。結果、ソフトウェアの品質は徐々に下がっていくということ。
課題は単純で、ソフトウェアが満たすべき性質(仕様)をソフトウェアの本体であるソースコードと一体で扱える環境がないこと。仕様の検証やテストが人力であり、振り返り、現状調査、情報の整合確認が必要となり、綿密な作業計画までも必要とされる場合さえあること。
これをいち早く解決できた事業はソフトウェア開発において大きなアドバンテーを得ることができるはずである。しかし、この分野はあまり注目をされない。バラダイムシフト以上のインパクトがあるし、技術者判断で適用困難な状況があるかもしれない。開発プロセスと密接に関連することであり、現状維持に傾きやすいのかもしれない。
この本が述べている関数プログラミングもパラダイムシフトである。現場への負担は小さくない。けれども課題の解消を実現できることを説明している。関数プログラミングを採用できなくても、なにがウィークポイントなのか、どのようにプロダクト開発へ適用できるのかのヒントにもなるだろう。考えるだけの価値は十分あると思う。
参照:
[haskell]リストの扱い参考サイト
とても参考になりました。ありがとう!
Haskellのリスト操作関数リストアップ(一覧)
[haskell]Data.IniをつかってINIファイルを読み書き
Data.Iniを使ってINIファイルを読み書きできるようになりました。ただ、ちょっと不味かろう、使い勝手悪かろうというという後味。
[haskell]iniファイルとexception
ini形式のデータをパースして値を取得できるようにします。また、ファイルが無いときの例外キャッチをできるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
{-# LANGUAGE ScopedTypeVariables #-} module Main where import qualified Data.HashMap as HM import qualified Data.Ini as Ini import qualified Data.Text as Tx import Control.Exception.Safe main::IO () main = do fi < - Ini.readIniFile "test.ini" `catch` (\(e::SomeException) -> do putStrLn $ displayException e return $ Ini.parseIni (Tx.pack "") ) case fi of Left fil -> putStrLn "" Right fir -> do putStrLn $ get (Tx.pack "あ") (Tx.pack "sessionId") fir putStrLn $ get (Tx.pack "い") (Tx.pack "sessionId") fir putStrLn $ getFromStr (Tx.pack "あ") return () where get::Tx.Text -> Tx.Text -> Ini.Ini -> String get section key ini = case Ini.lookupValue section key ini of Left l -> l Right r -> Tx.unpack r getFromStr::Tx.Text -> String getFromStr section = case Ini.parseIni (Tx.pack "[あ]\nhost=localhost\nport=6666\nsessionId=ない") of Left il -> il Right ir -> get section (Tx.pack "sessionId") ir |
1 2 3 4 5 6 7 8 9 10 |
~$ cat test.ini [あ] host=localhost port=6666 sessionId=0x0001 ~$ ./Main 0x0001 Couldn't find section: い < -- Left String ない ~$ |
lookupValueやparseIniは例外送出せず、値が見つからなき時はLeft Stringになります。
1 2 3 4 5 6 7 |
~$ rm test.ini ~$ ./Main test.ini: openFile: does not exist (No such file or directory) Couldn't find section: あ Couldn't find section: い ない ~$ |
catchはMonadCatchの型クラスを扱うためIOから抜けだせません。そのようなものなのでしょうか。理解できていません。
1 2 3 4 5 6 7 |
~$ cat test.ini sss ~$ ./Main Couldn't find section: あ Couldn't find section: い ない ~$ |
iniファイルのフォーマットに沿ってないファイル、単にセクションが見つからないだけです。パースはできています。
ちなみに実行ファイルサイズは4598736バイトでした。
[haskell][BNFC]n3337 Raw-string
n3337のRaw-stringをBNFCで定義する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
{- Unicode: Unicode scalar value Basic Multilingual Plane(BMP) = U+0000 - U+FFFF(*) Supplementary Multilingual Plane = U+010000 - U+10FFFF *) Reserved U+D800 - U+DFFF for Surrogate Pair encode rule. => char r-char: Any member of the source character set, except a right parenthesis ) followed by the initial d-char-sequence (which may be empty) followd by a double quote. => (char - [")"]) d-char: Any member of the basic source character set except: space, the left parenthesis (, the right parenthesis ), the backslash \, and the control characters representing horizontal tab, vertical tab, form feed, and newline. => (basic source char - ["() \\\t\v\f\n"]) 2.3 Character sets The basic source character set onsists of 96 characters: the space character, the control characters representing horizontal tab, vertical tab, form feed, and new-line, plus the following 91 graphical characters: a-z, A-Z, 0-9 and _{} []#() <>%:; .?*+- /^&|~ !=,\" ' => ["\t\v\f\n0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_{}[]#()<>%:;.?*+-/^&|~!=,\\\"\'"] -} LTest. Test::= Raw_string; token Raw_string ({"u8"} | ["uUL"])? {"R\""} (["\t\n0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_{}[]#()<>%:;.?*+-/^&|~!=,\\\"\'"] - ["() \\\t\n"])* '(' (char - [")"])* ')' (["\t\n0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_{}[]#()<>%:;.?*+-/^&|~!=,\\\"\'"] - ["() \\\t\n"])* '"'; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
~$ ./TestRawStr u8R"2sS(あ)6wY" Parse Successful! [Abstract Syntax] LTest (Raw_string "u8R\"2sS(\12354)6wY\"") [Linearized tree] u8R"2sS(あ)6wY" ~$ ~$ ./TestRawStr R"^^(あああ)^^" Parse Successful! [Abstract Syntax] LTest (Raw_string "R\"^^(\12354\12354\12354)^^\"") [Linearized tree] R"^^(あああ)^^" ~$ |
うまくパースしてくれているようです。
参考サイト