How to rewind in Go's text/scanner? - parsing

I am using text/scanner package to parse some arbitrary expressions. I am currently trying to implement a not in option, that is, if the current identifier is not, and the next is in, parse it using function notin(left, right), and otherwise we parse it as negate(right).
I've essentially got the code to manage these cases however, I am unable to rewind the scanner in case the next token is not in. I've tried by recording the position and then reassigning it later, but to no avail and haven't been able to find a different solution.
func readToken(stream *scanner.Scanner) {
switch stream.Scan() {
case scanner.Ident:
switch stream.TokenText() {
case "in":
in(left, right)
case "not":
oldPosition := stream.Position
nextToken := stream.Scan()
if nextToken == scanner.Ident {
switch stream.TokenText() {
case "in":
fmt.Println("notin")
default:
// how do we rewind the scanner?
stream.Position = oldPosition
fmt.Println("negate default")
}
} else {
fmt.Println("negate no-ident")
}
}
}
}
How can I rewind the scanner when I don't find a valid identifier?
Edit, I also tried using Peek() as below, but that still changes the state to the point that I'd need to rewind as well.
// other code
case "not":
nextIdent, err := getNextIdent(stream)
if err != nil {
fmt.Println("negate no-ident")
} else {
switch nextIdent {
case "in":
fmt.Println("notin")
default:
fmt.Println("negate default")
}
}
// other code
func getNextIdent(s *scanner.Scanner) (string, error) {
var nextIdent string
ch := s.Peek()
// skip white space
for s.Whitespace&(1<<uint(ch)) != 0 {
ch = s.Next()
}
if isIdentRune(ch, 0) {
nextIdent = string(ch)
ch = s.Next()
nextIdent += string(ch)
for i := 1; isIdentRune(ch, i); i++ {
ch = s.Next()
if s.Whitespace&(1<<uint(ch)) != 0 {
break
}
nextIdent += string(ch)
}
return nextIdent, nil
}
return "",errors.New("not a ident")
}
Note, the code I've got is a forked from Knetic/govaluate combined with a PR from GH user generikvault and some other forks. The full code can be found on my Github profile

By looking at the API references of text/scanner, I can't seem to find a way to rewind the scanner the way you want.
However, the Peek() method would get you the next rune without advancing the scanner. Inside the "not" case, you can use it to peek in advance to see if it matches.

Related

complementery of an if case

How would you write this:
if case .SomeEnum(3) = enumType where myInt == 3 {
//I don't need this case
} else {
//This is the case I need
}
I know I could use guard:
guard case .SomeEnum(3) = enumType where myInt == 3 else {
//This is the case I need
}
but I don't think it is clean, since it is not really a case in which the function is not able to finish. Also, guard expects me to return from the function.
Any other alternatives?
You cannot negate a pattern (as far as I know), and your first solution
using if/else looks fine to me, the intention of the code is clearly
visible.
A switch statement would be an alternative:
switch enumType {
case .SomeEnum(3) where myInt == 3:
break // I don't need this case
default:
// This is the case I need
// ...
}
With regard to your remark
Also, guard expects me to return from the function.
that is not entirely true. You are expected to leave the current scope.
So this would compile and work as expected:
repeat {
guard case .SomeEnum(3) = enumType where myInt == 3 else {
// This is the case I need
// ...
break
}
} while false
but I would not consider that a better solution.

Create a moving average (and other FIR filters) using ReactiveCocoa

I'm still getting started with ReactiveCocoa and functional reactive programming concepts, so maybe this is a dumb question.
ReactiveCocoa seem naturally designed to react to streams of live data, touch events or accelerometer sensor input etc.
Is it possible to apply finite impulse response filters in ReactiveCocoa in an easy, reactive fashion? Or if not, what would be the least-ugly hacky way of doing this? How would one go about implementing something like a simple moving average?
Ideally looking for an Swift 2 + RA4 solution but also interested in if this is possible at all in Objective C and RA2/RA3.
What you actually need is a some sort of period buffer, which will keep a period of values buffered and only start sending out when the buffer has reached capacity (the code below is heavenly inspired on takeLast operator)
extension SignalType {
func periodBuffer(period:Int) -> Signal<[Value], Error> {
return Signal { observer in
var buffer: [Value] = []
buffer.reserveCapacity(period)
return self.observe { event in
switch event {
case let .Next(value):
// To avoid exceeding the reserved capacity of the buffer, we remove then add.
// Remove elements until we have room to add one more.
while (buffer.count + 1) > period {
buffer.removeAtIndex(0)
}
buffer.append(value)
if buffer.count == period {
observer.sendNext(buffer)
}
case let .Failed(error):
observer.sendFailed(error)
case .Completed:
observer.sendCompleted()
case .Interrupted:
observer.sendInterrupted()
}
}
}
}
}
based on that you can map it to any algorithm you want
let pipe = Signal<Int,NoError>.pipe()
pipe.0
.periodBuffer(3)
.map { Double($0.reduce(0, combine: +))/Double($0.count) } // simple moving average
.observeNext { print($0) }
pipe.1.sendNext(10) // does nothing
pipe.1.sendNext(11) // does nothing
pipe.1.sendNext(15) // prints 12
pipe.1.sendNext(7) // prints 11
pipe.1.sendNext(9) // prints 10.3333
pipe.1.sendNext(6) // prints 7.3333
Probably the scan signal operator is what you're looking for. Inspired by Andy Jacobs' answer, I came up with something like this (a simple moving average implementation):
let (signal, observer) = Signal<Int,NoError>.pipe()
let maxSamples = 3
let movingAverage = signal.scan( [Int]() ) { (previousSamples, nextValue) in
let samples : [Int] = previousSamples.count < maxSamples ? previousSamples : Array(previousSamples.dropFirst())
return samples + [nextValue]
}
.filter { $0.count >= maxSamples }
.map { $0.average }
movingAverage.observeNext { (next) -> () in
print("Next: \(next)")
}
observer.sendNext(1)
observer.sendNext(2)
observer.sendNext(3)
observer.sendNext(4)
observer.sendNext(42)
Note: I had to move average method into a protocol extension, otherwise the compiler would complain that the expression was too complex. I used a nice solution from this answer:
extension Array where Element: IntegerType {
var total: Element {
guard !isEmpty else { return 0 }
return reduce(0){$0 + $1}
}
var average: Double {
guard let total = total as? Int where !isEmpty else { return 0 }
return Double(total)/Double(count)
}
}

golang : trouble with memory

I have trouble with memory. I don't understand why Go uses more and more memory (never freeing it) when my program runs for a long time.
After the first allocation, program uses nearly 9 MB of memory. Then after 12 hours it starts to use more memory exponentially, until 800 MB.
//.....code.....
if bol {
// Assignment Struct.Var
Struct_VastScript.TxtNoticeTop = JsonStruct_S.Options.TxtNoticeTop
Struct_VastScript.TxtNoticeBottom = JsonStruct_S.Options.TxtNoticeBottom
Struct_VastScript.Loop = JsonStruct_S.Options.Loop
Struct_Image, err := getImage(Struct_VastScript.Video)
if err == nil {
if mobile == "true" {
Struct_VastScript.Image = Struct_Image.URL360
}
}
//open and parse a template file
fi = path.Join("templates/VastPlayer", "TempVastPlayer.txt")
tmpl, err := template.ParseFiles(fi)
if err != nil {
job_1.Complete(health.Panic)
return false, err
}
//substitute fields in the template 'tmpl', with values from 'XmlStruct_V' and write it out to 'buf'
var buf bytes.Buffer
if err := tmpl.Execute(&buf, Struct_VastScript); err != nil {
//if err := tmpl.Execute(w, XmlStruct_V); err != nil {
job_1.Complete(health.Panic)
return false, err
}
// Call Func randString() : return alphanum random
dir := randString(12)
fpath := "http://creative2.xxx.io/api/html/" + dir
// Create a new EndPoint to write the generated 'template' on 'w' http.ResponseWriter
routeHtml := "/api/html/" + dir
http.HandleFunc(routeHtml, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//writes Template to 'w' http.ResponseWriter
fmt.Fprintf(w, buf.String())
fmt.Println("successfull Operation 2 !!")
fmt.Println("")
job_2.Complete(health.Success)
}))
//Call Func JsonReply(): return the finale Json response
str := JsonReply(fpath, JsonStruct_S.Options.Animated, JsonStruct_S.Options.Responsive, JsonStruct_S.Options.Clickurl, JsonStruct_S.Options.Width, JsonStruct_S.Options.Height, adid, campaignid, JsonStruct_S.Type, JsonStruct_S.Options.Aspectratio, mobile)
w.Header().Set("Content-Type", "application/json")
//writes FinaleJson to 'w' http.ResponseWriter(it contains the link of the second endpoint "/api/html/")
fmt.Fprint(w, str)
fmt.Println("successfull Operation !!")
fmt.Println("")
job_1.Complete(health.Success)
return true, nil
} else {
return false, nil
}
For each call,my service need to generate a new template with the params that I receive,as you see I create a new endpoint for each call, I don't know if it's a good idea, I think the problem comes from this part of code but Im not sure because I don't know how GO manage it.
Obviously, you should not create handler every time request appears. They never free the memory so you will end up having out of memory exception.
Instead, put the handler endpoint into array (slice) and use ONE handler that responds to the request by looking the URL in this slice and then removing the item from the slice with it is not needed any longer.
So basically, instead of
routeHtml := "/api/html/" + dir
http.HandleFunc(routeHtml, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//writes Template to 'w' http.ResponseWriter
fmt.Fprintf(w, buf.String())
fmt.Println("successfull Operation 2 !!")
fmt.Println("")
job_2.Complete(health.Success)
}))
do
type JobInfo struct {
Path string
// some data here
}
// maybe global context
var jobs []JobInfo
// initialisation
jobs = make([]JobInfo, 0)
http.HandleFunc("/api/html/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
var job *JobInfo
for _, j := range jobs {
if j.Path == path {
job = &j
break
}
}
if job != nil {
// handle job request here
}
}))
// and then in the jobs' loop
handlers = append(handlers, JobInfo{"/api/html/" + dir, ...})
It will work because:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
Do not forget to clean the array jobs, of course.
Instead of using slice it's better to use map
type JobInfo struct {
Path string
// some data here
}
// global context
var jobs map[string]JobInfo
// initialisation
jobs = make(map[string]JobInfoStruct)
http.HandleFunc("/api/html/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
var job JobInfoStruct
var ok bool
job, ok = jobs[path]
if ok {
// handle job request here
//then after delete the job
delete(jobs, path)
}
}))
// and then in the jobs' loop
pathVideo := "/api/html/" + dir
jobs[pathVideo] = JobInfoStruct{pathVideo, ...}

IOS Photon Cloud SDK getRoomList function doesn't work

I am developing cocos2d-x game which have online game mode.
Online game designed and implemented by Photon Cloud SDK(http://www.exitgames.com).
I implemented only ios version but it doesn't work.
The codes that I have implemented are blow.
void NetworkLogic::opJoinRandomRoom()
{
ExitGames::Common::JVector<ExitGames::LoadBalancing::Room> roomList;
roomList = mLoadBalancingClient.getRoomList();
int count = roomList.getSize();
CCLog("Room Count = %d", count);
if(count == 0)
{
this->opCreateRoom();
}else{
mLoadBalancingClient.opJoinRandomRoom();
}
}
void NetworkLogic::update(float dt)
{
this->run();
}
void NetworkLogic::run(void)
{
if(mLastInput == INPUT_EXIT && mStateAccessor.getState() != STATE_DISCONNECTING && mStateAccessor.getState() != STATE_DISCONNECTED)
{
disconnect();
mStateAccessor.setState(STATE_DISCONNECTING);
}
else
{
State state = mStateAccessor.getState();
switch(state)
{
case STATE_INITIALIZED:
connect();
mStateAccessor.setState(STATE_CONNECTING);
break;
case STATE_CONNECTING:
break; // wait for callback
case STATE_CONNECTED:
{
ExitGames::Common::JVector<ExitGames::LoadBalancing::Room> roomList;
roomList = mLoadBalancingClient.getRoomList();
int count = roomList.getSize();
ExitGames::Common::JString tmp;
tmp = count;
EGLOG(ExitGames::Common::DebugLevel::INFO, tmp);
CCLog("Room count in Room = %d", count);
switch(mLastInput)
{
case INPUT_CREATE_GAME: // create Game
opCreateRoom();
break;
case INPUT_JOIN_RANDOM_GAME: // join Game
opJoinRandomRoom();
mStateAccessor.setState(STATE_JOINING);
break;
default: // no or illegal input -> stay waiting for legal input
break;
}
break;
}
case STATE_JOINING:
break; // wait for callback
case STATE_JOINED:
switch(mLastInput)
{
case INPUT_LEAVE_GAME: // leave Game
mLoadBalancingClient.opLeaveRoom();
mStateAccessor.setState(STATE_LEAVING);
break;
default: // no or illegal input -> stay waiting for legal input
break;
}
break;
case STATE_LEAVING:
break; // wait for callback
case STATE_LEFT:
mStateAccessor.setState(STATE_CONNECTED);
break;
case STATE_DISCONNECTING:
break; // wait for callback
default:
break;
}
}
mLastInput = INPUT_NON;
mLoadBalancingClient.service();
}
First I run one app then getRoomList function returns 0 values.
Also after first room created and run second app but it also returns getRoomList function 0.
Please help me.
I have just taken the code that you have provided in your question and copied it into the according place inside the demo of an otherwise unchanged version 3.2.2.0 build of the Photon C++ Client SDK (and removed the two CCLog() lines to make it compile without cocos2d-x) and it worked just fine for me:
The demo prints 0 for the size of the room list until I let one client create a room. Afterwards the other client prints 1.

iOS UIAutomation UIAElement.isVisible() throwing stale response?

I'm trying to use isVisible() within a loop to create a waitForElement type of a function for my iOS UIAutomation. When I try to use the following code, it fails while waiting for an element when a new screen pops up. The element is clearly there because if I do a delay(2) before tapping the element it works perfectly fine. How is everyone else accomplishing this, because I am at a loss...
Here's the waitForElement code that I am using:
function waitForElement(element, timeout, step) {
if (step == null) {
step = 0.5;
}
if (timeout == null) {
timeout = 10;
}
var stop = timeout/step;
for (var i = 0; i < stop; i++) {
if (element.isVisible()) {
return;
}
target.delay(step);
}
element.logElement();
throw("Not visible");
}
Here is a simple wait_for_element method that could be used:
this.wait_for_element = function(element, preDelay) {
if (!preDelay) {
target.delay(0);
}
else {
target.delay(preDelay);
}
var found = false;
var counter = 0;
while ((!found) && (counter < 60)) {
if (!element.isValid()) {
target.delay(0.5);
counter++;
}
else {
found = true;
target.delay(1);
}
}
}
I tend to stay away from my wait_for_element and look for any activityIndicator objects on screen. I use this method to actual wait for the page to load.
this.wait_for_page_load = function(preDelay) {
if (!preDelay) {
target.delay(0);
}
else {
target.delay(preDelay);
}
var done = false;
var counter = 0;
while ((!done) && (counter < 60)) {
var progressIndicator = UIATarget.localTarget().frontMostApp().windows()[0].activityIndicators()[0];
if (progressIndicator != "[object UIAElementNil]") {
target.delay(0.25);
counter++;
}
else {
done = true;
}
}
target.delay(0.25);
}
Here is a simple and better one using recursion. "return true" is not needed but incase u want it.
waitForElementToDismiss:function(elementToWait,waitTime){ //Using recursion to wait for an element. pass in 0 for waitTime
if(elementToWait && elementToWait.isValid() && elementToWait.isVisible() && (waitTime < 30)){
this.log("Waiting for element to invisible");
target.delay(1);
this.waitForElementToDismiss(elementToWait, waitTime++);
}
if(waitTime >=30){
fail("Possible login failed or too long to login. Took more than "+waitTime +" seconds")
}
return true;
}
Solution
I know this is an old question but here is my solution for a situation where I have to perform a repetitive task against a variable timed event. Since UIAutomation runs on javascript I use a recursive function with an empty while loop that checks the critical control state required before proceeding to the next screen. This way one never has to hard code a delay.
// Local target is the running simulator
var target = UIATarget.localTarget();
// Get the frontmost app running in the target
var app = target.frontMostApp();
// Grab the main window of the application
var window = app.mainWindow();
//Get the array of images on the screen
var allImages = window.images();
var helpButton = window.buttons()[0];
var nextButton = window.buttons()[2];
doSomething();
function doSomething ()
{
//only need to tap button for half the items in array
for (var i=0; i<(allImages.length/2); i++){
helpButton.tap();
}
//loop while my control is NOT enabled
while (!nextButton.isEnabled())
{
//wait
}
//proceed to next screen
nextButton.tap();
//go again
doSomething();
}

Resources