いろきゅう.jp 〜Programmable maiden〜 Tech side このページをアンテナに追加 RSSフィード

goto OTA side >>

2017-02-10

gawk「cmd. line:1: (FILENAME=- FNR=1) fatal: print to "standard output" failed (No space left on device)」で死亡

| 00:31

コマンドプロンプトGow に収録されている gawkGNU Awk 3.1.0) を使用すると、以下のメッセージを吐きグズりはじめることがあります。 どうやら日本語を吐こうとすると死ぬ模様。 粗相

gawk: cmd. line:1: (FILENAME=- FNR=1) fatal: print to "standard output" failed (No space left on device)

対策

WILLs’ trash can さんで配布されている、マルチバイト対応の gawk を使用しましょう。 GNU Awk 3.0.6 ベースとちょっと古いですが何とかなるでしょううん(他人事

トラックバック - http://d.hatena.ne.jp/ir9Ex/20170210

2017-01-12

文字列比較を == して死亡どころか大爆死

| 18:25

public boolena empty(String s)
{
  return (s == null) || (s == "");
}

なんてJavaで書いちゃって死亡。 後者は "".equals(s) が正しいですね。すいませんマジすいませんでした。おのれJava!!



とはいえ、JUnitでテストした関数だったんですよ。 問題ないじゃーんと。

assertTrue(empty(null)); // OK!
assertTrue(empty(""));   // OK!


ですが、この empty() を本番コードで以下のように使っていました(イメージ)

final String   csvData = ",,,"; // テストで空カラムデータを投げた
final String[] cols    = csvData.split(",");
if(empty(cols[0])) return false;
if(empty(cols[1])) return false;
if(empty(cols[2])) return false;
  :
  :

ステップオーバーで if() を素通りする姿に 10秒ぐらい頭真っ白になったね! そうだよね! コード直書きの空文字 "" のインスタンスは同じ可能性があるけど、split() して誕生した空文字 "" はインスタンスまず別だよね! そりゃ false だよね!

…いやーもうなんか恥ずかしい。 おのれJava!!

トラックバック - http://d.hatena.ne.jp/ir9Ex/20170112

2016-12-16

yaccで死亡

| 17:59

正確には ply の yacc ですけどももも

…いやぁ全然概念が判らなくて大苦戦ですわ(苦笑




学習がてら、以下に合致するパーサーを作ろうかと思ったわけです。ドット区切りで要素3つまで。

  • a
  • b.a
  • c.b.a
  • 正規表現的にはこんな感じ → ((\w+\.)?\w\.)?\w+

イメージ的には foo.ir9.jp / ir9.jp / jp を解析するパーサーを作りたい的な。 で、こんな感じなの書きました

## lex
tokens = (
	"NAME",
	"PERIOD",
)

t_NAME   = r"\w+"
t_PERIOD = r"\."

## yacc
def p_host(p):
	"""
	host : NAME PERIOD NAME PERIOD NAME
	     | NAME PERIOD NAME
	     | NAME
	"""

	p[0] = ''.join(p[1:])

yacc.yacc()
print(yacc.parse("c.b.a"))	# c.b.a
print(yacc.parse("b.a"))	# b.a
print(yacc.parse("a"))		# a

動きました。良かったよかった!

…ではあるんですが、各NAMEの要素に名前というか意味合いを付けたほうがよいのかなと。今後各要素に適用できる文字の定義を変えるかもしれないし! …ってことで、次のように改修してみました。 "[ [sub . ] domain .] cont" というイメージ。

## lex
tokens = (
	"NAME",
	"PERIOD",
)

t_NAME   = r"\w+"
t_PERIOD = r"\."

## yacc
def p_host(p):
	"""
	host : domain PERIOD cunt
	     | NAME
	"""

	p[0] = ''.join(p[1:])

def p_cunt(p) :
	"""
	cunt : NAME
	"""
	p[0] = p[1]

def p_domain(p) :
	"""
	domain : sub PERIOD NAME
	       | NAME
	"""
	p[0] = ''.join(p[1:])

def p_sub(p) :
	"""
	sub : NAME
	"""
	p[0] = p[1]

yacc.yacc()
print(yacc.parse("c.b.a"))	# a // Syntax error at line 1, token=PERIOD
print(yacc.parse("b.a"))	# b.a
print(yacc.parse("a"))		# a

# WARNING: 1 reduce/reduce conflict
# WARNING: reduce/reduce conflict in state 3 resolved using rule (domain -> NAME)
# WARNING: rejected rule (sub -> NAME) in state 3
# WARNING: Rule (sub -> NAME) is never reduced

ダメだってさ!



…って所でめっちゃ詰まってます。 おそらく「スタックに NAME 積んだ後 PERIOD 来ると、domain なんだか sub なんだか判断つかねぇんだよ!2回死ね!それと便座カバー」って事だとは思っているんですが、いかんせん yacc の挙動・動作・考え方が解っていないため全く確信が持てず。 ついでに解決方法も良くわからん… そもそもコレ「右結合」なんじゃないのと思いつつ、それがどう記述に影響してくるのか・考え方にどう影響してくるのかとかもよくわからず… ぐぬぬ……

構文解析難しいわ…

トラックバック - http://d.hatena.ne.jp/ir9Ex/20161216

2016-12-02

xpathで死亡

| 14:55

例えば「id=foo の属性を持つノードを親・先祖に持たない a要素全て」を選択する xpath が書けぬ…

//*[@id!="foo"]//a

とか書いても、先祖に div#foo があるノードが抽出されてしまった…。 そりゃそうか。 仮に "/body/div#foo/span/a" と階層あったとして、body や span は id="foo" じゃないし…

ancestor とやらを使えばなんとかなりそうな気がしたものの、全く上手く扱えず死亡。

誰かボスケテ

トラックバック - http://d.hatena.ne.jp/ir9Ex/20161202