Tässä on työn alla C++:lla koodatun projektin porttaaminen C#:lle. Kyseessä on cocos2d-x pelimoottori ja yritän tehdä PHP-skriptiä, jolla koodin voi helposti muuttaa C++:sta C#:ksi.
Netistä löytyy kyllä ohjelmia syntaksin muuttamiseen, mutta nämä cocos2d-x:ään liittyvät jutut pitää tehdä käsin.
// spriten luominen c++:lla CCSprite* spr = CCSprite::create("foo.png");
// spriten luominen c#:lla CCSprite spr = new CCSprite("foo.png");
C++:n staattiset funktiot on siis korvattu C#:ssa erilaisilla konstruktoreilla.
Ongelma: luomani regex ei toimi kaikissa tapauksissa, esim. tästä koodista regex osaa muuttaa vain ensimmäisen rivin.
Lähde:
// käyttämäni c++ -> c# konversio-ohjelma palauttaa tämän CCSprite spr = CCSprite.createWithTest("test.png"); CCSprite spr = CCSprite.create("test.png"); public partial class MainMenu { public bool init() { CCSprite spr = CCSprite.create("test.png"); CCSprite spr = CCSprite.createWithTest("test.png"); } }
Tulos:
CCSprite spr = new CCSprite("test.png"); // Ok CCSprite spr = CCSprite.create("test.png"); // ei toimi public partial class MainMenu { public bool init() { CCSprite spr = CCSprite.create("test.png"); // ei toimi CCSprite spr = CCSprite.createWithTest("test.png"); // ei toimi } }
Regex:
preg_replace('/([a-zA-Z]+)\.create[a-zA-Z]*\((.*)\)/', "new $1($2)", $source);
Outoa, koska minulla antamasi säännöllinen lauseke muuttaa molemmat rivit oikein.
Yksi mahdollinen ongelma on siinä, että (.*)
ottaa mukaan mahdollisimman paljon merkkejä eikä lopeta ensimmäiseen loppusulkuun. Korjaus tähän on muuttaa kyseinen kohta muotoon (.*?)
. Tämän ei pitäisi kuitenkaan vaikuttaa tapaukseesi, koska .
ei täsmää rivinvaihtoon.
Kysymysmerkin laittaminen korjasi ongelman... Osaatko Antti selittää miksi näin tapahtuu? Eikö .*? tarkoita "mikä tahansa merkki 0+ kertaa, 0 tai 1 kertaa".
PHP-oppaasta...
https://www.ohjelmointiputka.net/oppaat/opas.
Kysymysmerkki määrittää, että lausekkeen osa tunnistaa mahdollisimman lyhyen pätkän tekstiä. Ilman kysymysmerkkiä tunnistettava osa olisi mahdollisimman pitkä --
Lisäys: Eli tuossa (.*?)-tapauksessa näin. Mutta esim. bracket expressionin perässä täsmää juurikin 0-1 kertaa.
Kysymysmerkki toisto-operaattorin perässä tarkoittaa, että toisto-operaattori ei ole ahne (greedy) vaan laiska (lazy) eli ottaa mahdollisimman vähän toistoja.
Nykyinenkin (tai korjattu) lausekkeesi toimii periaatteessa väärin sulkujen kanssa: vaikkapa tekstistä ”A.create(f(1),2)” tunnistetaan puutteellinen pätkä ”A.create(f(1)” eli sulut eivät mene tasan ja toinen parametri puuttuu. Jos vaikka korvauksessa olisi uudet sulut koko koodin ympärillä, tuloksena olisi ”new (A(f(1)),2)” eli selvästi viallinen koodi.
Koska et lausekkeessa muuta sulkuja tai niiden sisältöä, voit jättää lausekkeesta kokonaan pois kohdan ”(.*)\)” ja vastaavasti korvauksesta kohdan ”$2)”.
Aihe on jo aika vanha, joten et voi enää vastata siihen.