How to identify grammar is LR(0) or SLR(1)? - theory

Is this grammar LR(0) or SLR(1)?
S -> E $
E -> T + E | T
T -> x

The following diagram proves that this grammar is NOT in LR(0) (it has a shift reduce conflict):
+--------------+ E +------------+
| |----------> | S -> E . $ |
| S -> . E $ | +------------+
| E -> . T + E |
| E -> . T | T +--------------+ state 2
| T -> . x |----------> | E -> T . + E | This state contains a
| | | E -> T . | Shift-Reduce conflict.
+--------------+ +--------------+
| | + ^
| x V | T
| +--------------+
V | E -> T + . E |
+---------------+ x | E -> . T + E | +--------------+
| T -> x . | <---------| E -> . T |--------> | E -> T + E . |
+---------------+ | T -> . x | +--------------+
+--------------+
However, it IS in SLR(1) because the conflict in state 2 can be resolved by using the fact that the + token is not in FOLLOW(E).
Since SLR(1) parsers can look 1 token ahead, they can decide to shift in state 2 if the next token is + (and solve the conflict by doing so).
If the SLR(1) parser is in state 2, and next token is +,
why not choose reduce?
Well, suppose the parser chooses to reduce E -> T.
Then eventually the + token will be read, and it will follow either E,
or some other variable that E was derived from (only S in this grammar).
But neither E nor S can have the + token (immediately) follow them!

Related

Creating grammars for lexical analyzer

I am trying to create a lexical analyzer for a given language. Can't write grammar rules correctly. My task is
The input language contains conditional statements if ... then ... else and if ... then, separated by a symbol ; (semicolon). Condition statements contain identifiers, comparison signs <,>, =, hexadecimal numbers, sign assignments (:=). Consider the sequence as hexadecimal numbers digits and symbols a, b, c, d, e, f starting with a digit (for example, 89, 45ac, 0abc )
I got these rules:
S -> if E then S else S; S | if E then S; S | if E then S else S | if E then S | I := E
E -> H | E > H | E < H | E = H
I -> LLL
H -> DHL | DL | DH |D
L -> a | b | c | d | e | f
D -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Is the rule (H -> DHL | DL | D | DH) for determining hexadecimal numbers set correctly? Are the rest of the rules correct?

representing a grid board with c

Might be quite a dumb question but I somehow managed to create an empty grid board looking like
A B C D E F G H
+---+---+---+---+---+---+---+---+
1 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
2 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
3 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
4 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
5 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
6 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
7 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
8 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
int
main(int argc, char *argv[]) {
int c;
printf("%6c", 65);
for (c = 66; c <= 72; c++) {
printf("%4c", c);
}
printf("\n");
printf(" +---+---+---+---+---+---+---+---+");
for (c = 1; c <= 8; c++) {
printf("\n%2d |", c);
for (int d = 1; d <= 8; d++) {
printf(" . |");
}
printf("\n +---+---+---+---+---+---+---+---+");
}
}
is it possible to allocate each '.' with an according grid location (e.g: B1, G5 etc) in C?
edit : single character replacement would be fine so for example if I want to create a chess board (capital for White, non-capital for Black) it would look something like
A B C D E F G H
+---+---+---+---+---+---+---+---+
1 | r | b | n | q | k | n | b | r |
+---+---+---+---+---+---+---+---+
2 | p | p | p | p | p | p | p | p |
+---+---+---+---+---+---+---+---+
3 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
4 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
5 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
6 | . | . | . | . | . | . | . | . |
+---+---+---+---+---+---+---+---+
7 | P | P | P | P | P | P | P | P |
+---+---+---+---+---+---+---+---+
8 | R | B | N | Q | K | N | B | R |
+---+---+---+---+---+---+---+---+
p/P for pawn
r/R for rook
b/B for bishop
n/N for knight
q/Q for queen
k/K for king

Having trouble with Postgres unnest array syntax

I am looking for guidance on the best way to do this insert. I am trying to create 11 entries for role_id 58385 while looping through the values of each of these arrays. I am new to PostgreSQL and need some guidance as to what I am doing wrong in this instance.
INSERT INTO public.acls (role_id, acl_id, update, can_grant, retrieve, create, archive) VALUES (
'58385',
unnest(array[1,14,20,21,22,24,25,26,36,300,302]),
unnest(array[f,f,t,t,f,f,f,t,f,t,t]),
unnest(array[f,f,f,f,f,f,f,f,f,f,f]),
unnest(array[t,t,t,t,t,t,t,t,t,t,t]),
unnest(array[f,f,t,t,f,f,f,t,f,t,t]),
unnest(array[f,f,f,f,f,f,f,f,f,f,f])
)
Do I need a SELECT subquery for each of the arrays? Or could I make one array from the six and Insert them.
A single select will do it for you, but t and f will need to be true and false:
select '58385',
unnest(array[1,14,20,21,22,24,25,26,36,300,302]),
unnest(array[false,false,true,true,false,false,false,true,false,true,true]),
unnest(array[false,false,false,false,false,false,false,false,false,false,false]),
unnest(array[true,true,true,true,true,true,true,true,true,true,true]),
unnest(array[false,false,true,true,false,false,false,true,false,true,true]),
unnest(array[false,false,false,false,false,false,false,false,false,false,false])
;
?column? | unnest | unnest | unnest | unnest | unnest | unnest
----------+--------+--------+--------+--------+--------+--------
58385 | 1 | f | f | t | f | f
58385 | 14 | f | f | t | f | f
58385 | 20 | t | f | t | t | f
58385 | 21 | t | f | t | t | f
58385 | 22 | f | f | t | f | f
58385 | 24 | f | f | t | f | f
58385 | 25 | f | f | t | f | f
58385 | 26 | t | f | t | t | f
58385 | 36 | f | f | t | f | f
58385 | 300 | t | f | t | t | f
58385 | 302 | t | f | t | t | f
(11 rows)

How to return first not empty cell from importrange values?

my google sheet excel document contain data like this
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | | c | | x | |
+---+---+---+---+---+---+
| 2 | | r | | 4 | |
+---+---+---+---+---+---+
| 3 | | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
Column B and D contain data provided by IMPORTRANGE function, which are store in different files.
And i would like to fill column A with first not empty value in row, in other words: desired result must look like this:
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | c | c | | x | |
+---+---+---+---+---+---+
| 2 | r | r | | 4 | |
+---+---+---+---+---+---+
| 3 | m | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
I tried ISBLANK function, but apperantly if column is imported then, even if the value is empty, is not blank, so this function dosn't work for my case. Then i tried QUERY function in 2 different variant:
1) =QUERY({B1;D1}; "select Col1 where Col1 is not null limit 1"; 0) but result in this case is wrong when row contain cells with numbers. Result with this query is following:
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | c | c | | x | |
+---+---+---+---+---+---+
| 2 | 4 | r | | 4 | |
+---+---+---+---+---+---+
| 3 | m | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
2) =QUERY({B1;D1};"select Col1 where Col1 <> '' limit 1"; 0) / =QUERY({B1;D1};"select Col1 where Col1 != '' limit 1"; 0) and this dosn't work at all, result is always #N/A
Also i would like to avoid using nested IFs and javascript scripts, if possible, as solution with QUERY function suits for my case best due to easy expansion to another columns without any deeper knowladge about programming. Is there any way how to make it simply, just with QUERY, and i am just missing something, or i have to use IFs/javascript?
try:
=ARRAYFORMULA(SUBSTITUTE(INDEX(IFERROR(SPLIT(TRIM(TRANSPOSE(QUERY(
TRANSPOSE(SUBSTITUTE(B:G, " ", "♦")),,99^99))), " ")),,1), "♦", " "))
selective columns:

Find all possible relationships between two nodes in multi-parent hierarchy data model [SQL Server]

I have a data model to define multi-parent hierarical data. Each record will represent a relationship of two nodes in which one will be a parent node and another will be a child node. In my case, a node can have multiple parents. I need to find all possible relationsips between two nodes.
For example take the below table.
---------------------------------
| id | parent_node | child_node |
---------------------------------
| 1 | NULL | A |
| 2 | NULL | B |
| 3 | A | C |
| 4 | A | D |
| 5 | B | D |
| 6 | B | E |
| 7 | C | G |
| 8 | C | H |
| 10 | D | I |
| 11 | E | I |
| 12 | E | J |
---------------------------------
This will form a graph like below
A B
/ \ / \
C D E
/ \ \ / \
G H I J
In the above model, A and B will be the top level node and each has two children. Node D is assigned as the child of node A and B. And also node I is assigned as the child of node D and node E. All other nodes has exactly one parent.
I need to write a query to show all possible relationship of a node with another node.
For example,
A and C has a relationship, because C is child of Node A.
A and D has a relationship, because D is child of Node A.
A and G has a relatiohship, because G is the grandchild of Node A.
This will go for any number of levels.
Two nodes doesn't have any relationship, if any one node is not a child or nth-level grandchild of another.
If two nodes doesn't have any relationship, it will not show up.
The final outcome for the above graph will be as below,
----------------------------
| parent_node | child_node |
----------------------------
| A | C |
| A | D |
| C | G |
| C | H |
| D | I |
| A | G |
| A | H |
| A | I |
| B | D |
| B | E |
| B | I |
| E | I |
| E | J |
| B | J |
----------------------------
I am new to SQL Server. Please help me to solve this query.
By doing some research, I was able to write the query myself. As #SeanLange pointed out in the comments, this type of query is called a recursive CTE.
If the table name is nodes, the following query will create the new table relationship and store all possible relationships in it as mentioned in my question.
;with cte as (
select child_node
, parent_node
, child_node as root
from nodes
union all
select child.child_node
, child.parent_node
, parent.root
from cte parent
join nodes child
on parent.parent_node = child.child_node
)
select parent_node,
root as child_node
into relationship
from cte
where parent_node is not null;
select * from relationship;

Resources