I am trying to parse some text with Parse::RecDescent
from :
x=2 and y=2 and f=3 and (x has 3,4 or r=5 or r=6 ) and z=2
to something like :
x equal 2 and y equal 2 and f equal 3 and (( x contains 3 or x contains 4 or r equal 5 or requal 6 )) and z equal 2
other example :
input :
x= 3 and y has 5 and (z has 6 or z=3 ) and f=2
output :
x equals 3 and (( y contains 5)) and ((z has 6 or z equals 3)) and f equals 2
my question if i find a list of those operators :
has ,or
i should put "((" before the code and "))" after the code as mentioned on the example aboves
is it possible to do something like this with Parse::RecDescent ?
The grammar would look something like the following:
parse : expr EOF
expr : logic_or
# vvv Lowest precedence vvv
logic_or : <leftop: logic_and LOGIC_OR logic_and>
logic_and : <leftop: comparison LOGIC_AND comparison>
comparison : term comparison_[ $item[1] ]
comparison_ : '=' term
| HAS ident_list
|
# ^^^ Highest precedence ^^^
ident_list : <leftop: IDENT ',' IDENT>
term : '(' expr ')'
| IDENT
# Tokens
IDENT : /\w+/
LOGIC_OR : /or\b/
LOGIC_AND : /and\b/
HAS : /has\b/
EOF : /\Z/
Now you just need to add the code block to emit the desired output.
In comparison_, the LHS term is available as $arg[0].
I had to make some assumptions, so there could be errors.
Related
I am struggling to write a nprev function in KDB; xprev function returns the nth element but I need all the prev n elements relative to the current element.
q)t:([] i:1+til 26; s:.Q.a)
q)update xp:xprev[3;]s,p:prev s from t
Any help is greatly appreciated.
You can achieve the desired result by applying prev repeatedly and flipping the result
q)n:3
q)select flip 1_prev\[n;s] from t
s
-----
" "
"a "
"ba "
"cba"
"dcb"
"edc"
..
If n is much smaller than the rows count, this will be faster than some of the more straightforward solutions.
The xprev function basically looks like this :
xprev1:{y til[count y]-x} //readable xprev
We can tweak it to get all n elements
nprev:{y til[count y]-\:1+til x}
using nprev in the query
q)update np: nprev[3;s] , xp1:xprev1[3;s] , xp: xprev[3;s], p:prev[s] from t
i s np xp1 xp p
-------------------
1 a " "
2 b "a " a
3 c "ba " b
4 d "cba" a a c
5 e "dcb" b b d
6 f "edc" c c e
k equivalent of nprev
k)nprev:{$[0h>#y;'`rank;y(!#y)-\:1+!x]}
and similarly nnext would look like
k)nnext:{$[0h>#y;'`rank;y(!#y)+\:1+!x]}
I can't decipher this line of code. Could someone please translate it into if / else statements?
I understand the basic CONDITION ? VALUE_IF_TRUE : VALUE_IF_FALSE pattern, but this line seems to break that.
$type = $self->{1}{_flag} & 2 ?
$self->{2}{_flag} & 2 ? "A" : "B" :
$self->{2}{_flag} & 2 ? "B" : "C";
I think it's irresponsible to write code like that where the operator precedence is far from obvious
Using a mixture of if / else and conditional expressions it looks much clearer like this
if ( $self->{1}{_flag} & 2 ) {
$type = $self->{2}{_flag} & 2 ? "A" : "B";
}
else {
$type = $self->{2}{_flag} & 2 ? "B" : "C";
}
A couple of line breaks makes all the difference, although I've also added some parens to make it crystal clear.
$type = $self->{1}{_flag} & 2
? ( $self->{2}{_flag} & 2 ? "A" : "B" )
: ( $self->{2}{_flag} & 2 ? "B" : "C" );
That's almost as cryptic as the equivalent
$type = (qw/C x B x A/)[ $self->{1}{_flag} & 2 + $self->{2}{_flag} & 2 ];
More seriously, nesting ternary operators in the true-branch is confusing. I'd use an explicit if/else. Or if I really wanted a ternary, I'd rearrange this to:
$type = $self->{1}{_flag} & 2 != $self->{2}{_flag} & 2
? 'B'
: $self->{1}{_flag} & 2
? 'A'
: 'C';
how can i specify a mathematical expression using Z notation ?
I think free types is appropriate for this situation because expressions has a recursive nature. please consider that we can have parenthesis and variables in our expression. and only ( + , - , / , * ) is allowed. for example :
A + 2 * ( 3 - B ) / 4
please help me ...
You need to use the axiomatic definition: the definition of an object is constrained by conditions.
There is a schema specified in zet for this.
Which is
| Declaration
------------------------------
| Predicate
|
|
A recursive example given:
[USERNAME] - An already defined type.
Given a username and a sequence of usernames(N1 --> USERNAME) return the number that the given username appears into the sequence.
|-occurs- USERNAME X seq USERNAME → N //here you define the input and what is returned.
---------------------------------------
|∀ u: USERNAME, s: seq USERNAME then
|s = < > => occurs(u,s) = 0
|s ≠ < > and head(s) = u => occurs(u,s) = 1+occurs(u,tail(s))
|s ≠ < > and head(s) ≠ u => occurs(u,s) = occurs(u,tail(s))
I need help simplifying the following Boolean expressions using DeMorgan’s law:
a) [ (AB)' + (CD)' ]'
and
b) [(X+Y)' + (X+Y') ]'
Please show some steps so I can do the other ones myself
a)
First step is the outermost negation: distribute it.
((AB)')'*((CD)')'
You see we have double negations which means the expression itself. (p')' = p
therefore
ABCD
[ (AB)' + (CD)' ]' --> ABCD
b)
Distribute the outermost negation:
((X+Y)')'(X+Y')'
get rid of the double negation:
(X+Y)(X+Y')'
again, distribute the negation (the one at the outer part of the expression):
(X+Y)(X'Y)
When you distribute (X+Y), we get
XX'Y + YX'Y
Since there is XX' in the first part of disjunction, the expression XX'Y equals to 0 (False).
Multiple instances of the same thing in an expression is the same thing itself. ppp = p.
Therefore:
0 + YX' --> YX'
[ (X+Y)' + (X+Y') ]' --> YX'
Im sorry for non-formal language:) hope it helps.
Steps are included:
a: [ (AB)' + (CD)' ]' = (AB)'' * (CD)'' = (AB) * (CD) = ABCD
b: [ (X+Y)' + (X+Y') ]' = (X+Y)'' * (X+Y')' = (X+Y) * (X'*Y) .. Simplifying this further relies on the distributive property.
Is there a way to express this in a less repeative fashion with the optional positive and negative signs?
What I am trying to accomplish is how to express optionally provide positive + ( default ) and negative - signs on number literals that optionally have exponents and or decimal parts.
NUMBER : ('+'|'-')? DIGIT+ '.' DIGIT* EXPONENT?
| ('+'|'-')? '.'? DIGIT+ EXPONENT?
;
fragment
EXPONENT : ('e' | 'E') ('+' | '-') ? DIGIT+
;
fragment
DIGIT : '0'..'9'
;
I want to be able to recognize NUMBER patterns, and am not so concerned about arithmetic on those numbers at that point, I will later, but I am trying to understand how to recognize any NUMBER literals where numbers look like:
123
+123
-123
0.123
+.123
-.123
123.456
+123.456
-123.456
123.456e789
+123.456e789
-123.456e789
and any other standard formats that I haven't thought to include here.
To answer your question: no, there is no way to improve this AFAIK. You could place ('+' | '-') inside a fragment rule and use that fragment, just like the exponent-fragment, but I wouldn't call it a real improvement.
Note that unary + and - signs generally are not a part of a number-token. Consider the input source "1-2". You don't want that to be tokenized as 2 numbers: NUMBER[1] and NUMBER[-2], but as NUMBER[1], MINUS[-] and NUMBER[2] so that your parser contains the following:
parse
: statement+ EOF
;
statement
: assignment
;
assignment
: IDENTIFIER '=' expression
;
expression
: addition
;
addition
: multiplication (('+' | '-') multiplication)*
;
multiplication
: unary (('*' | '/') unary)*
;
unary
: '-' atom
| '+' atom
| atom
;
atom
: NUMBER
| IDENTIFIER
| '(' expression ')'
;
IDENTIFIER
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | DIGIT)*
;
NUMBER
: DIGIT+ '.' DIGIT* EXPONENT?
| '.'? DIGIT+ EXPONENT?
;
fragment
EXPONENT
: ('e' | 'E') ('+' | '-') ? DIGIT+
;
fragment
DIGIT
: '0'..'9'
;
and addition will therefor match the input "1-2".
EDIT
An expression like 111.222 + -456 will be parsed as this:
and +123 + -456 as: