Tokenize un langage basé sur la pile

15

J'ai travaillé sur un autre langage de golf basé sur la pile appelé Stackgoat . Dans ce défi, vous allez écrire un Tokenizer pour Stackgoat (ou vraiment n'importe quel langage général basé sur la pile).

Exemples

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

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

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

"foo
['"foo"']

(empty input)
[]

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

spécification

Les trois types que vous devrez gérer sont:

  • Cordes, n'importe quoi à l' intérieur""
  • Numéros, n'importe quelle séquence de chiffres
  • Opérateurs, tout autre caractère en plus des espaces

Les espaces sont essentiellement ignorés, sauf s'ils se trouvent dans une chaîne ou séparent deux nombres.

Spécification chaîne / caractère:

  • Les chaînes sont délimitées par un ", et quand un \est rencontré, le caractère suivant doit être échappé.
  • Les caractères sont précédés d'un 'et le caractère après le 'doit être converti en un littéral de chaîne. 'a->"a"
  • ' aura toujours un caractère après
  • Les guillemets de clôture doivent être insérés automatiquement

Règles:

  • Aucune forme de evaln'est autorisée

Entrée sortie:

  • L'entrée peut être effectuée via STDIN, les paramètres de fonction ou l'équivalent de votre langue.
  • La sortie doit être un tableau ou l'équivalent le plus proche de votre langue.
Downgoat
la source
5
@ Doorknob, sérieusement?
LegionMammal978
4
@ LegionMammal978 Oui, sérieusement.
Alex A.
1
La sortie peut-elle être vers STDOUT?
Poignée de porte
2
@ZachGates Eh bien oui, la plupart des langues gèrent aussi \ comme un caractère d'échappement, donc oui, vous devrez y échapper si votre langue en a évidemment besoin.
Downgoat
1
De plus, dans le premier exemple, le premier élément du résultat devrait- '"PPCG"'il être au lieu de juste "PPCG"?
Fund Monica's Lawsuit

Réponses:

8

Rétine , 68 64 63 octets

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

ou

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

Je pense que cela couvre tous les cas funky edge, même ceux qui ne sont pas couverts par les cas de test du défi.

Essayez-le en ligne!

Martin Ender
la source
Dang, c'est court. Bien fait!
Fund Monica's Lawsuit
J'ai pu traduire cela en une fonction ES6 de 95 octets. Il aurait été de 80, sauf que les expressions rationnelles ne fonctionnent pas dans le sens inverse (trop de cas marginaux).
Neil
2

Rubis, 234 octets

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', '}]"

J'ai essayé d'utiliser l' find(&:itself)astuce que j'ai vue ... quelque part, mais ce .itselfn'est apparemment pas une méthode. En outre, je travaille sur le regex, mais c'est déjà illisible.

Si nous n'avons pas besoin de sortir de façon fantaisiste (c'est-à-dire que les chaînes n'ont pas à être citées dans le tableau), je peux enregistrer un grand nombre d'octets:

Still Ruby, 194 octets:

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?)

Je suis sûr que je peux jouer au golf plus, mais je ne sais pas trop comment.


Ungolfed arrive bientôt. J'ai commencé à jouer avec le golf directement à un moment donné et je vais devoir le taquiner.

Action en justice de Fund Monica
la source
0

Python 3, 228 octets

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())],[]))))))

Voici une belle, longue doublure.


Testez-le en Python 3. Voici quelques exemples:

$ 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
' ""
['" "', '""']
Portes Zach
la source