ときどきの雑記帖 RE* (新南口)
ペギミンH
ホンダ
またF1のニュースで「ホンダ勝利」のキャプションをJRE車内ニュースで見かけるなど。 本文では「レッドブル・ホンダ」になってたけど。
ジロ・デ・イタリア
「ジロ・ディタリア」という表記をとあるニュースで見かけ、一瞬なんぞそれはと思ったが、 考えてみれば「Giro d’Italia」なんだからそっちの方が元の音に近いのか。
今週のしずえさん
セイヨウタンポポが日本に持ち込まれた理由(目的)
BM法
基本情報技術者試験の問題にも出てくるのですな。
基本情報技術者過去問題 平成27年秋期 午後問8(データ構造及びアルゴリズム)|基本情報技術者試験.com
そう言えば某翻訳家(「本業」は違ったかもしれない)が C マガジンという古の雑誌で持っていた連載のどこかで BM法の実装間違えて云々というエピソードがあったと思うんだけど いつの話でどんな話だったっけか。
えーと…
【Character Encodings】文字コードについて軽くまとめておく
RE_CONTEXT_INDEP_OPS
色々ツッコミどころはあるんだけどいちいち挙げていくのは面倒なのでひとつだけ。
% grep -E ‘*’ /etc/motd
実行結果(WordPressのDockerコンテナにて試しています。実行環境によって結果は異なります)
で
% grep -E '*' /etc/motd
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
「*」は「アスタリスク」と読み、0回以上の連続する繰り返しを意味します。この場合、/etc/motdというファイルの中から、 0回以上の連続する繰り返しを探し出して表示しています。つまり、全部表示します。
はいくらなんでもおかしな結果な気がするんだけど。
使っているgrepがわからないけど多分GNU grepだよね。 この例のように「繰り返す対象がない」(繰り返しを指定する)メタ文字は その「文字」そのものとして扱われるかエラーになるかのどちらかのはずなんだがなあ。
glibc の場合だとこんな感じ(regcomp.c)
static bin_tree_t *
parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
{
...省略...
case OP_DUP_ASTERISK:
case OP_DUP_PLUS:
case OP_DUP_QUESTION:
if (syntax & RE_CONTEXT_INVALID_OPS)
{
*err = REG_BADRPT;
return NULL;
}
else if (syntax & RE_CONTEXT_INDEP_OPS)
{
fetch_token (token, regexp, syntax);
return parse_expression (regexp, preg, token, syntax, nest, err);
}
FALLTHROUGH;
case OP_CLOSE_SUBEXP:
RE_CONTEXT_INVALID_OPS
はさておきRE_CONTEXT_INDEP_OPS
はというと
/* If this bit is set, then special characters are always special
regardless of where they are in the pattern.
If this bit is not set, then special characters are special only in
some contexts; otherwise they are ordinary. Specifically,
* + ? and intervals are only special when not after the beginning,
open-group, or alternation operator. */
# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
こういう意味になっていて、GNU grep ではこのフラグは有効になっている。
[B! 正規表現] 正規表現を学んでみませんか | さくらのナレッジ
続 Conditional Expressions with Omitted Middle-Operands
前回 gccにおけるconditioal expression の第2オペランドの扱いについて、
GNU C/C++ (GCCによる拡張) では、三項演算子の第二項を省略することができる[4]。GCC 2.95.3より使用可能[5] (March 2001)。
は違うだろう、少なくとも1.4.2ですでにそうだったぞということを書いたけど、 Index of /pub/gcc/old-releases/gcc-1 にさらに古いものがあるのを見つけたので調べてみた。 ただ、2.95.3であったような詳細なドキュメントは含まれていなかったので ソースコードを見てみた。
1.21 ではconditinal expression の構文定義はこうなっていて
| expr_no_commas '?' xexpr ':' expr_no_commas
{ $$ = build_conditional_expr ($1, $3, $5); }
ここで xexpr はというとこう
xexpr:
/* empty */
{ $$ = NULL_TREE; }
| expr
;
つまりは空でも良い=省略できるということですね。
実際、省略できる式の置けるforの定義も同様に xexprが使われている。
| FOR
'(' xexpr ';'
{ emit_note (input_filename, @1.first_line);
if ($3) expand_expr_stmt ($3);
expand_start_loop_continue_elsewhere (1); }
xexpr ';'
{ emit_note (input_filename, @6.first_line);
if ($6)
expand_exit_loop_if_false (truthvalue_conversion ($6)); }
xexpr ')'
/* Don't let the tree nodes for $9 be discarded
by clear_momentary during the parsing of the next stmt. */
{ push_momentary (); }
stmt
ということでこの時点(1.21)ですでにこの機能はあったということですね (undocumented なものだった可能性はある)。
ところで先のサイトに置かれているもので最も古い(バージョンが若い)のは 1.21ではなく0.9だったりするのだけど、 それではこうなっている
| expr_no_commas '?' expr ':' expr_no_commas
{ $$ = build_conditional_expr($1, $3, $5); }
はい。これは省略できませんね。
ということで、0.9以降1.21までのどこかで入ったのだろう。というのが今日の結論。 ただし、1.21のChangeLogにはこれに関する記述は見つからなかったので、 1.0になるまでには入ってたんじゃないかとは思う。
おまけ
英語版うぃきぺ Elvis operator - Wikipedia にも日本語版と同様の記述があった(ここを翻訳したのか?)ので読んでみると
In GNU C and C++ (that is: in C and C++ with GCC extensions), the second operand of the ternary operator is optional.[3] This has been the case since at least GCC 2.95.3 (March 2001), and seems to be the original elvis operator.[4]
なんで「at least」を無視してんだよ>日本語版
glob(そのn+2)
v7unix/v7/usr/src/cmd/sh at master ・ v7unix/v7unix
のコードをつらつらと眺めていると
v7unix/cmd.c at ed636a47207476db76d53b7869447889dee3bbad ・ v7unix/v7unix
にあるLOCAL TREPTR term(flg)
という関数で
IF (t=item(TRUE)) ANDF (wdval=='^' ORF wdval=='|')
THEN return(makelist(TFIL, makefork(FPOU,t), makefork(FPIN|FPCL,term(NLFLG))));
ELSE return(t);
FI
と書かれているのに気がついた。
パイプの部分の処理だと思うんだけど、これだと
^
でも
|
と同様にパイプを構成できるのでは?
と思い調べてみた
(まあ環境作ってビルドして実行するのが近道の気もするけど)。
- Pipeline (Unix) - Wikipedia
- Redirection (computing) - Wikipedia
- History of pipes concept
- Bourne Shell - Wikipedia
といったところをめぐってもこれという記述は見つからず。 そう言えば
辺りで、パイプの記号の変遷とか読んだような気もするなあと 思い出したが手元になかった(笑)
じゃあ
はどうだろうと見てみたもののそれっぽい(^
でパイプ)記述は見当たらず。
そのあとも色々探しているとThompson Shell - Wikipedia でこういう記述を見つけた。
Version 3 のマニュアルによると、当初のパイプ構文は次のようなものだった。
command1 >command2>
しかしこの構文は非常に紛らわしく、ファイル入出力のリダイレクトと混同しやすいことが分かった。 Version 4 になると、パイプを表現するために | と ^ を使うよう改められた。
command1 | command2
これは次のように入力しても同じである。
command1 ^ command2
ふむ。Bourne Shellでもこれが残っていたということなのか?
Hugo メモ
Hugo(で作るサイト)にコメント機能をつけるというものらしい。
- domeniko-gentner/labertasche: Comment system for GoHugo.io
- (1) Labertasche - a comment system for Hugo, written in Python Flask and JS : programming