I want to define simple grammar for UCI protocol but I have some problems with it.
I want parse such line:
id name hello world
Nothing complex I wrote such grammar:
grammar s01_uci;
id_name
: 'id' SPACE 'name' SPACE ID_NAME
;
SPACE
: ' '
;
ID_NAME
: .+?
;
LINE_END
: '\r\n'
| '\r'
| '\n'
;
My Pycharm Antlr4 plugin shows that only 'id name h' is parsed rest is not visible to parser. Why it happens - wrong lexer rules?
It look simple that I should match token but maybe I define too much token or not enough in Lexer - I have not idea how to improve it after reading many articles.
Some example of lines to be parsed (input is lines not file):
id name Stockfish 10 64 BMI2
id author T. Romstad, M. Costalba, J. Kiiski, G. Linscott
option name Debug Log File type string default
option name Contempt type spin default 24 min -100 max 100
option name Analysis Contempt type combo default Both var Off var White var Black var Both
option name Threads type spin default 1 min 1 max 512
option name Hash type spin default 16 min 1 max 131072
option name Clear Hash type button
option name Ponder type check default false
option name MultiPV type spin default 1 min 1 max 500
option name Skill Level type spin default 20 min 0 max 20
option name Move Overhead type spin default 30 min 0 max 5000
option name Minimum Thinking Time type spin default 20 min 0 max 5000
option name Slow Mover type spin default 84 min 10 max 1000
option name nodestime type spin default 0 min 0 max 10000
option name UCI_Chess960 type check default false
option name UCI_AnalyseMode type check default false
option name SyzygyPath type string default <empty>
option name SyzygyProbeDepth type spin default 1 min 1 max 100
option name Syzygy50MoveRule type check default true
option name SyzygyProbeLimit type spin default 7 min 0 max 7
uciok
Related
Problem (Tested on Lua 5.3 and 5.4):
a = -9223372036854775807 - 1 ==> -9223372036854775808 (lua_integer)
b = -9223372036854775808 ==> -9.2233720368548e+018 (lua_number)
Question:
Is it possible to get "-9223372036854775808" without modify "luaconf.h" or write "-9223372036854775807 - 1"?
When you write b = -9223372036854775808 in your program, the Lua parser treats this as "apply negation operator to positive integer constant", but positive constant is beyond integer range, so it's treated as float, and negation is applied to the float number, and the final result is float.
There are two solutions to get minimal integer:
Bitwise operators convert floats to integers (bitwise OR has lower priority then negation):
b = -9223372036854775808|0
Use the special constant from math library:
b = math.mininteger
P.S.
Please note that additional OR in the expression b = -9223372036854775808|0 does not make your program slower. Actually, all calculations (negation and OR) are done at compile time, and the bytecode contains only the final constant you need:
$ luac53 -l -l -p -
b = -9223372036854775808|0
main <stdin:0,0> (2 instructions at 0x244f780)
0+ params, 2 slots, 1 upvalue, 0 locals, 2 constants, 0 functions
1 [1] SETTABUP 0 -1 -2 ; _ENV "b" -9223372036854775808
2 [1] RETURN 0 1
constants (2) for 0x244f780:
1 "b"
2 -9223372036854775808
locals (0) for 0x244f780:
upvalues (1) for 0x244f780:
0 _ENV 1 0
I have two metrics with matching labels, both counters:
accounts_created_total{provider="auth0"} 738
accounts_created_total{provider="google} 980
accounts_deleted_total{provider="auth0"} 65
I'd like to calculate the number of existing accounts from those two metrics. I came up with this:
accounts_created_total - accounts_deleted_total
# which results in
{provider="auth0"} 673
# Note the missing provider="Google"
Unfortunately, there's no account_deleted_total for provider="Google", and so I only get the result for provider="auth0".
Is there a way I can tell prometheus to "make up" the missing labels? That would typically be equivalent to a coalesce in SQL.
You can complete a time serie using the OR binary operator:
vector1 or vector2 results in a vector that contains all original elements
(label sets + values) of vector1 and additionally all elements of vector2
which do not have matching label sets in vector1.
Assuming you want to default accounts_deleted_total to 0, the following expression uses accounts_created_total as second vector to extract the labels and multiplying by 0 ensures the value is reset:
accounts_deleted_total OR (accounts_created_total * 0)
In the case of autho0, the label exists in accounts_deleted_total and the second part will not be used ; to the contrary, for google, second part will yield
{provider="google"} 0
Finally, you can use it in your expression:
accounts_created_total - (accounts_deleted_total OR (accounts_created_total * 0))
In your specific case, since you are using the same metric to extract the labels, you can even simplify the expression to:
(accounts_created_total - accounts_deleted_total) OR accounts_created_total
I would like to implement a DSL for setting port numbers on a socket object.
I would like the DSL to follow this API for setting the host port number:
host: 8080
If this were a string operation (such as host: localhost) I could use parse-word. That's less than ideal though, since Forth is very good at parsing numbers, and re-inventing the wheel is a bad thing.
Are there any standard words in Forth that take the first item on the input string, parse it to a number and push it on the stack?
>NUMBER is an ANS word (in CORE) that turns strings into numbers, but it's cumbersome to use. Your Forth probably has a more flexible variant. Your Forth probably also supports syntax like #16 $10 %10000, which all evaluate to 16, regardless of BASE. So one way to do this:
: parse-num ( "number" -- n | d | r ) parse-word evaluate ;
Or with >NUMBER, and only returning a single-cell number:
: parse-num ( "number" -- n )
0. parse-word >number ( d c-addr u )
abort" not a number" drop
abort" double received where single-cell number expected" ;
Which aborts if the returned string isn't the empty string that would result if the entire output of PARSE-WORD was converted into a number, or if the high bits of the double aren't 0, which would be the case if a number not representable by a cell were entered. (NB. >NUMBER doesn't handle double-number syntax either. It will stop parsing 1. at the dot. It doesn't even handle negative numbers.)
I have a variable named A in SPSS database.
A
--
102102
23453212
142378
2367890654
2345
45
I want to split this variable by 2 lengths and create multiple variables as follows.
A_1 A_2 A_3 A_4 A_5
--- --- --- --- ---
10 21 02
23 45 32 12
14 23 78
23 67 89 06 54
23 45
45
Can anyone write SPSS macro to compute this operation?
Using STRING manipulations (after converting the NUMERIC field to STRING, if necessary), specifically SUBSTR you can extract out pairs of digits as you wish.
/* Simulate data */.
data list list / x (f8.0).
begin data.
102102
23453212
142378
2367890654
2345
45
end data.
dataset name dsSim.
If you have a known maximum value, in your example a value of 10 digits long then you'll need 5 variables to store the pairs of digits, which the follow does:
preserve.
set mxwarns 0 /* temporarily supress warning messages */ .
string #xstr (a10).
compute #xstr=ltrim(string(x,f18.0)).
compute A_1=number(substr(#xstr,1,2), f8.0).
compute A_2=number(substr(#xstr,3,2), f8.0).
compute A_3=number(substr(#xstr,5,2), f8.0).
compute A_4=number(substr(#xstr,7,2), f8.0).
compute A_5=number(substr(#xstr,9,2), f8.0).
exe.
restore.
However, you may prefer to code something like this more dynamically (using python) where the code itself would read the maximum value in the data and create as many variables as needed.
begin program.
import spssdata, math
spss.Submit("set mprint on.")
# get maximum value
spss.Submit("""
dataset declare dsAgg.
aggregate outfile=dsAgg /MaxX=max(x).
dataset activate dsAgg.
""")
maxvalue = spssdata.Spssdata().fetchone()[0]
ndigits=math.floor(math.log(maxvalue,10))+1
cmd="""
dataset close dsAgg.
dataset activate dsSim.
preserve.
set mxwarns 0.
string #xstr (a10).
compute #xstr=ltrim(string(x,f18.0)).
"""
for i in range(1,int(math.ceil(ndigits/2))+1):
j=(i-1)*2+1
cmd+="\ncompute B_%(i)s=number(substr(#xstr,%(j)s,2), f8.0)." % locals()
cmd+="\nexe.\nrestore."
spss.Submit(cmd)
spss.Submit("set mprint off.")
end program.
You would need to weigh up the pros on cons of each method to asses which suits you best, for how you anticipate your data to arrive and how you then go onto work with in later. I haven't attempted to wrap either of these up in a macro but that could just as easily be done.
I have a file with data
number name age sex
102234 James_Mckenzie 21 M
102233 Jim_Reil 24 M
102235 Alan_Lightbrighter 19 M
...
and I am trying to print them out in such form
number :
name : age :
sex :
so basically, the printout will be like this,
number : 102233
name : Jim_Reil age : 24
sex : M
number : 102235
name : Alan_Lightbrighter age : 19
sex : M
...
The problem is I am trying to keep up with spacing between name and age, but due to the variable name length, the position of 'age' is not where I am want(I used /t for spacing)
What would be the best way to fix this issue?
I am sorry if this has been asked thousand times already.(I spend some time searching but I guess my search keyword sucked :( )
Thanks
Don't use tabs for spacing since that relies entirely on the vagaries of your terminal.
Figure out what the largest name is likely to be and use printf with a %-50s format specifier (50 characters wide, left justified) on your name, as per the following transcript:
$ echo '1 pax X
2 paxdiablo_with_a_very_long_name Y' | awk '{printf "%3d %-40s %s\n",$1,$2,$3}'
1 pax X
2 paxdiablo_with_a_very_long_name Y
Or, closer to your requirements:
$ echo '102234 James_Mckenzie 21 M
102233 Jim_Reil 24 M
102235 Alan_Lightbrighter 19 M' | awk '
{printf "number : %d\nname : %-20s age : %d\nsex : %s\n",$1,$2,$3,$4}'
number : 102234
name : James_Mckenzie age : 21
sex : M
number : 102233
name : Jim_Reil age : 24
sex : M
number : 102235
name : Alan_Lightbrighter age : 19
sex : M
Obviously, the 50 and 20 are examples - you should choose a size that suits your needs. If necessary, you could even go through the file on the first pass to work out the largest name and then use a format string constructed from that in a second pass to print, but that's probably overkill.