スタックベースの言語をトークン化する


15

私は、に取り組んできた別のと呼ばれるスタックベースのゴルフの言語Stackgoat。この課題では、Stackgoat(または実際には一般的なスタックベースの言語)のTokenizerを作成します。

"PPCG"23+
["PPCG", '23', '+']

'a "bc" +
['"a"', '"bc"', '+']

12 34+-"abc\"de'fg\\"
['12', '34', '+', '-', '"abc\"de'fg\\"']

"foo
['"foo"']

(empty input)
[]

' ""
['" "', '""']

仕様

処理する必要がある3つのタイプは次のとおりです。

  • ストリングス、何も""
  • 数字、数字列
  • 演算子、空白以外の任意の単一文字

空白は、文字列内にあるか、2つの数値を区切っていない限り、本質的に無視されます。

文字列/文字仕様:

  • 文字列はで区切られ、が検出された"場合\、次の文字をエスケープする必要があります。
  • '文字はa で始まり、その後の'文字は文字列リテラルに変換されます。'a->"a"
  • ' 常にその後に文字があります
  • 終値を自動挿入する必要があります

ルール:

  • の形式evalは許可されません

入出力:

  • 入力は、STDIN、関数パラメーター、または同等の言語を通じて取得できます。
  • 出力は、配列または言語に最も近いものでなければなりません。

5
@Doorknob、真剣に?
LegionMammal978

4
@ LegionMammal978はい、真剣に。
アレックスA.

1
出力はSTDOUTにできますか?
ドアノブ

2
@ZachGatesはい、ほとんどの言語は\もエスケープ文字として処理します。そのため、言語で明らかに必要な場合は、エスケープする必要があります。
ダウンゴート

1
また、最初の例では、結果の最初の要素'"PPCG"'は単にではなく"PPCG"
ファンドモニカの訴訟

回答:


8

網膜68 64 63バイト

M!s`"(\\.|[^"])*"?|'.|\d+|\S
ms`^'(.)|^"(([^\\"]|\\.)*$)
"$1$2"

または

s`\s*((")(\\.|[^"])*(?<-2>")?|'.|\d+|.)\s*
$1$2¶
\ms`^'(.)
"$1"

これは、チャレンジのテストケースでカバーされていないものも含め、ファンキーなエッジケースをすべてカバーしていると思います。

オンラインでお試しください!


ダン、これは短い。よくできました!
ファンドモニカの訴訟

これを95バイトのES6関数に変換できました。正規表現が逆に動作しないことを除いて、80だったでしょう(エッジケースが多すぎる)。
ニール

2

ルビー、234バイト

puts"[#{$stdin.read.scan(/("(?:(?<!\\)\\"|[^"])+(?:"|$))|'(.)|(\d+)|(.)/).map{|m|(m[0]?(m[0].end_with?('"')?m[0]: m[0]+'"'): m[1]?"\"#{m[1]}\"": m.compact[0]).strip}.reject(&:empty?).map{|i|"'#{/\d+|./=~i ?i: i.inspect}'"}.join', '}]"

私がfind(&:itself)見たトリックをどこかで使ってみました...どこかですが、.itself実際には方法ではありません。また、私は正規表現を下にゴルフに取り組んでいますが、それはすでに読めません。

派手な方法で出力する必要がない場合(つまり、文字列を配列内で引用する必要がない場合)、1ロット全体を保存できます。

まだルビー、194バイト:

p$stdin.read.scan(/("(?:(?<!\\)\\"|[^"])+(?:"|$))|'(.)|(\d+)|(.)/).map{|m|(m[0]?(m[0].end_with?('"')?m[0]: m[0]+'"').gsub(/\\(.)/,'\1'): m[1]?"\"#{m[1]}\"": m.compact[0]).strip}.reject(&:empty?)

もっとゴルフできると確信していますが、どのようにすればいいのかよくわかりません。


Ungolfedはすぐに来ます。ある時点で直接ゴルフをいじり始めたので、それをいじらなければなりません。


0

Python 3、228バイト

import re;L=list
print(L(map(lambda i:i+'"'if i[0]=='"'and not i[-1]=='"'else i,map(lambda i:'"%s"'%i[1]if i[0]=="'"else i,filter(None,sum([L(i)for i in re.findall('(\'.)|(".*")|(\d+)|([^\w\"\'\s\\\])|(".*"?)',input())],[]))))))

素敵な、長い、2ライナーです。


Python 3でテストします。例をいくつか示します。

$ python3 test.py
"PPCG"23+
['"PPCG"', '23', '+']

$ python3 test.py
'a "bc" +
['"a"', '"bc"', '+']

$ python3 test.py
12 34+-"abc"de'fg\"
['12', '34', '+', '-', '"abc"de\'fg\\"']

$ python3 test.py
"foo
['"foo"']

$ python3 test.py

[]

$ python3 test.py
' ""
['" "', '""']
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.