delete left recursion in a grammar - grammar

I have this grammar:
agent
= nil
| #
| id
| act . agent
| agent + agent
| agent "|" agent
| agent \ restriction
| agent [relabeling]
| agent where agent_frame end
| automation
| (agent)
where the priorities are:
"where" < "+" < "|" < "\" < "." < "[" < "nil", "#"
I need to delete the left recursion respecting the priorities ( and write all in JavaCC).
Can you help me to delete recursion?

Dinesh thank you for the answer,
your solution give me a conflict in JavaCC with (agent-postfix)*.
I solved in this way:
agent=agent2 agent'
agent'= "where" agent_frame "end" agent' | epsilon
agent2= agent3 agent2'
agent2'= "+" agent3 agent2' | epsilon
agent3= agent4 agent3'
agent3'= "|" agent4 agent3' | epsilon
agent4 = agent5 agent4'
agent4'= "\" restriction agent4' | epsilon
agent5: act "." agent | agent6
agent6 = agent7 agent6'
agent6'= "[" relabeling "]" agent6' | epsilon
agent7= id | automaton | "(" agent ")" | "nil" | "#"
but I don't know if this solution is correct.
Thank you very much.
Regards
Domenico

I'm no JavaCC expert, but here is how you can get started to get rid of your left recursion:
agent-primary
= nil
| #
| id
| act . agent
| automation
| (agent)
agent-postfix
= + agent
| "|" agent
| \ restriction
| [relabeling]
| where agent_frame end
agent
= agent-primary (agent-postfix)*
You might face some conflicts with the right agent calls as well in the "binary" expressions such as agent + agent.
In any case, your grammar looks very similar to arithmetic expressions, so I advice you to have a look at how these are typically handled in JavaCC.

Related

Print logs only when the tests failed in karate

With Karate API tests, I would like to print the request and reponse only when the test fails.
How can I achieve that in karate.
Consider the below scenarios
Feature: Validate Addition.
Background:
Scenario Outline: Verify Addition
* def sum = <num1> + <num2>
And match sum == 10
* print "number1:" + num1 + " number2:" + num2
Examples:
| num1 | num2 |
| 5 | 5 |
| 7 | 3 |
| 3 | 8 |
| 1 | 5 |
| 1 | 9 |
In the above scenario I get the print for every iteration. Is it possible to print the numbers only when the match fails.
I think it would be more efficient if we can have such option.
Short answer is that it is not possible. You can try contributing code to make this happen. Or maybe you should use REST-assured or Selenium - those sound more like a good fit for you, based on all your questions.
One thought is that you can switch off all logging by making the levels ERROR etc. and then write some custom hook. Refer to hooks here: https://stackoverflow.com/a/60944060/143475
Also refer to how to create custom reports here: https://stackoverflow.com/a/66773839/143475

How to eval a string containing column names?

As I cannot attach a conditional formatting on a Table, I need an abstract function to chech if a set of records or all records have errors inside, and show these errors into forms and/or reports.
Because, to achieve this goal in the 'standard' mode, I have to define the rule [○for a field of a table every time I use that field in a control or report, and this means the need to repeate the same things an annoying lot of times, not to tell about introducing errors and resulting in a maintenance nightmare.
So, my idea is to define all the check for all the tables and their rows in an CheckError-table, like the following fragment related to the table 'Persone':
TableName | FieldName | TestNumber | TestCode | TestMessage | ErrorType[/B][/COLOR]
Persone | CAP | 4 | len([CAP]) = 0 or isnull([cap]) | CAP mancante | warning
Persone | Codice Fiscale | 1 | len([Codice Fiscale]) < 16 | Codice fiscale nullo o mancante | error
Persone | Data di nascita | 2 | (now() - [Data di nascita]) < 18 * 365 | Minorenne | info
Persone | mail | 5 | len([mail)] = 0 or isnull([mail] | email mancante | warning
Persone | mail | 6 | (len([mail)] = 0 or isnull([mail]) | richiesto l'invio dei referti via e- mail, | error
| | | and [modalità ritiro referti] = ""e-mail"" | ma l'indirizzo e-mail è mancante |
Persone | Via | 3 | len([Via]) = 0 or isnull([Via]) | Indirizzo mancante | warning
Now, in each form or report which use the table Persona, I want to set an 'onload' property to a function
' to validate all fields in all rows and set the appropriate bg and fg color
Private Sub Form_Open(Cancel As Integer)
Call validazione.validazione(Form, "Persone", 0)
End Sub
' to validate all fields in the row identified by ID and set the appropriate bg and fg color
Private Sub Codice_Fiscale_LostFocus()
Call validazione.validazione(Form, "Persone", ID)
End Sub
So, the function validazione, at a certain point, as exactly one row for the table Persone, and the set of expressions described in the column [TestCode] above.
Now, I need to logically evaluate the TestString against the table row, to obtain a true or a false.
If true, I'll set the fg and bg color of the field as normal
if false, I'll set the the fg and bg color as per error, info or warning, as defined by the column [ErrorType] above.
All the above is easy, ready, and running, except for the red statement above:
How can I evaluate the teststring against the table row, to obtain a result?
Thank you
Paolo

Excel VBA - How to insert comma after each word in a column

I have a column that contains multiple word strings. Like this:
+---+-------------------------------+--------------+-------------------------------+--------------+-------------------------------+-------------------------------+
| | A | B | C | D | E | F |
+---+-------------------------------+--------------+-------------------------------+--------------+-------------------------------+-------------------------------+
| 1 | Early Summer Lawn Application | Service Call | Early Summer Lawn Application | Grub Control | Early Summer Lawn Application | Early Summer Lawn Application |
+---+-------------------------------+--------------+-------------------------------+--------------+-------------------------------+-------------------------------+
My question is how can I insert a comma after each word in the column, to end up with:
+---+-------------------------------+--------------+-------------------------------+--------------+-------------------------------+-------------------------------+
| | A | B | C | D | E | F |
+---+-------------------------------+--------------+-------------------------------+--------------+-------------------------------+-------------------------------+
| 1 | Early,Summer,Lawn,Application | Service,Call | Early,Summer,Lawn,Application | Grub,Control | Early,Summer,Lawn,Application | Early Summer Lawn Application |
+---+-------------------------------+--------------+-------------------------------+--------------+-------------------------------+-------------------------------+
Its ok to lose the space between the words and its ok if the results are in a different column, I just don't know how to insert the commas.
Won't a simple replace work here?
=replace(A1," ", ",")
replaces space with comma. The other function is
=substitute(A1, " ", ",")
also works, but substitute has another argument that might come in handy. It specifies which occurrence to substitute. For example, if you only wanted to replace the first blank space with comma but leave other blank spaces as is, then try this:
=substitute(A1, " ", ",", 1)
Bottom line, use replace if you know where to replace (position), and use substitute if you know what to replace (content). Either would work for a narrow class of problems as you discovered.
The following example erplaces programmatically all spaces with commas:
Sub example()
Dim s1 As String, s2 As String
Dim pos As Integer
s1 = ActiveSheet.ActiveCell.Value
s2 = ""
pos = InStr(1, s1, " ")
While (pos <> 0)
s2 = s2 & Mid(s1, 1, pos - 1) & ","
s1 = Mid(s1, pos + 1)
pos = InStr(1, s1, " ")
Wend
s2 = s2 & s1
ActiveSheet.ActiveCell.Value = s2
End Sub

Optimizing working scheduling MiniZinc code - constraint programming

Please can you help optimize this working MiniZinc code:
Task: There is a conference which has 6x time slots. There are 3 speakers attending the conference who are each available at certain slots. Each speaker will present for a predetermined number of slots.
Objective: Produce the schedule that has the earliest finish of speakers.
Example: Speakers A, B & C. Talk durations = [1, 2, 1]
Speaker availability:
+---+------+------+------+
| | Sp.A | Sp.B | Sp.C |
+---+------+------+------+
| 1 | | Busy | |
| 2 | Busy | Busy | Busy |
| 3 | Busy | Busy | |
| 4 | | | |
| 5 | | | Busy |
| 6 | Busy | Busy | |
+---+------+------+------+
Link to working MiniZinc code: http://pastebin.com/raw.php?i=jUTaEDv0
What I'm hoping to optimize:
% ensure allocated slots don't overlap and the allocated slot is free for the speaker
constraint
forall(i in 1..num_speakers) (
ending_slot[i] = starting_slot[i] + app_durations[i] - 1
) /\
forall(i,j in 1..num_speakers where i < j) (
no_overlap(starting_slot[i], app_durations[i], starting_slot[j], app_durations[j])
) /\
forall(i in 1..num_speakers) (
forall(j in 1..app_durations[i]) (
starting_slot[i]+j-1 in speaker_availability[i]
)
)
;
Expected solution:
+---+----------+----------+----------+
| | Sp.A | Sp.B | Sp.C |
+---+----------+----------+----------+
| 1 | SELECTED | Busy | |
| 2 | Busy | Busy | Busy |
| 3 | Busy | Busy | SELECTED |
| 4 | | SELECTED | |
| 5 | | SELECTED | Busy |
| 6 | Busy | Busy | |
+---+----------+----------+----------+
I'm hakank (author of the original model). If I understand it correctly, your question now is how to present the table for the optimal solution, not really about finding the solution itself (all FlatZinc solvers I tested solved it in no time).
One way of creating the table is to have a help matrix ("m") which contain information if a speaker is selected (1), busy (-1) or not available (0):
array[1..num_slots, 1..num_speakers] of var -1..1: m;
Then one must connect info in this the matrix and the other decision variables ("starting_slot" and "ending_slot"):
% connect to matrix m
constraint
forall(t in 1..num_slots) (
forall(s in 1..num_speakers) (
(not(t in speaker_availability[s]) <-> m[t,s] = -1)
/\
((t >= starting_slot[s] /\ t <= ending_slot[s]) <-> m[t,s] = 1)
)
)
;
Then the matrix "m" can be printed like this:
% ...
++
[
if s = 1 then "\n" else " " endif ++
if fix(m[t,s]) = -1 then
"Busy "
elseif fix(m[t,s]) = 1 then
"SELECTED"
else
" "
endif
| t in 1..num_slots, s in 1..num_speakers
]
;
As always, there are more than one way of doing this, but I settled with this since it's quite direct.
Here's the complete model:
http://www.hakank.org/minizinc/scheduling_speakers_optimize.mzn
Update: Adding the output of the model:
Starting: [1, 4, 3]
Durations: [1, 2, 1]
Ends: [1, 5, 3]
z: 5
SELECTED Busy
Busy Busy Busy
Busy Busy SELECTED
SELECTED
SELECTED Busy
Busy Busy
----------
==========
Update 2:
Another way is to use cumulative/4 instead of no_overlap/4 which should be more effective, i.e.
constraint
forall(i in 1..num_speakers) (
ending_slot[i] = starting_slot[i] + app_durations[i] - 1
)
% /\ % use cumulative instead (see below)
% forall(i,j in 1..num_speakers where i < j) (
% no_overlap(starting_slot[i], app_durations[i], starting_slot[j], app_durations[j])
% )
/\
forall(i in 1..num_speakers) (
forall(j in 1..app_durations[i]) (
starting_slot[i]+j-1 in speaker_availability[i]
)
)
/\ cumulative(starting_slot, app_durations, [1 | i in 1..num_speakers], 1)
;
Here's the altered version (which give the same result)
http://www.hakank.org/minizinc/scheduling_speakers_optimize2.mzn
(I've also skipped the presentation matrix "m" and do all presentation in the output section.)
For this simple problem instance, there is no discernible difference, but for larger instances this should be faster. (And for larger instances, one might want to test different search heuristics instead of "solve minimize z".)
As I commented on your previous question Constraint Programming: Scheduling speakers in shortest time, the cumulative constraint is appropriate for this. I don't have Minizinc code handy, but there is the model in ECLiPSe (http://eclipseclp.org):
:- lib(ic).
:- lib(ic_edge_finder).
:- lib(branch_and_bound).
solve(JobStarts, Cost) :-
AllUnavStarts = [[2,6],[1,6],[2,5]],
AllUnavDurs = [[2,1],[3,1],[1,1]],
AllUnavRess = [[1,1],[1,1],[1,1]],
JobDurs = [1,2,1],
Ressources = [1,1,1],
length(JobStarts, 3),
JobStarts :: 1..9,
% the jobs must not overlap with each other
cumulative(JobStarts, JobDurs, Ressources, 1),
% for each speaker, no overlap of job and unavailable periods
(
foreach(JobStart,JobStarts),
foreach(JobDur,JobDurs),
foreach(UnavStarts,AllUnavStarts),
foreach(UnavDurs,AllUnavDurs),
foreach(UnavRess,AllUnavRess)
do
cumulative([JobStart|UnavStarts], [JobDur|UnavDurs], [1|UnavRess], 1)
),
% Cost is the maximum end date
( foreach(S,JobStarts), foreach(D,JobDurs), foreach(S+D,JobEnds) do true ),
Cost #= max(JobEnds),
minimize(search(JobStarts,0,smallest,indomain,complete,[]), Cost).

Robot Framework - Case sensitive

I need to know if there is a workaround on this error:
When I use Keywords like:
Location Should Be
Location Should Contain
(Which are both part of the Selenium2Library.)
I get this error:
"Location should have been 'http://www.google.pt' but was 'http://WwW.GooGLe.Pt'
I think that is because robot framework is natively case sensitive when comparing strings.
Any help?
Ty
EDIT
Question edited to clarify some subjects.
Luckily Robot Framework allows for keywords to be written in python.
MyLibrary.py
def Compare_Ignore_Case(s1, s2):
if s1.lower() != s2.lower():
return False
else:
return True
def Convert_to_Lowercase(s1):
return s1.lower()
MySuite.txt
| *Setting* | *Value* |
| Library | ./MyLibrary.py |
| *Test Case* | *Action* | *Argument*
#
| T100 | [Documentation] | Compare two strings ignoring case.
| | Compare Ignore Case | foo | FOO
#
| T101 | [Documentation] | Compare two strings where one is a variable.
# Should be Get Location in your case.
| | ${temp}= | MyKeyword that Returns a String
| | Compare Ignore Case | foo | ${temp}
I have not used the Selenium library, but the example in T101 should work for you.
Just in case someone else wants this:
Location should be '${expectedUrl}' disregard case
${currUrl} get location
${currUrl} evaluate "${currUrl}".lower()
${expectedUrl} evaluate "${expectedUrl}".lower()
should be equal ${currUrl} ${expectedurl}
Location should contain '${expected}' disregard case
${currUrl} get location
${currUrl} evaluate "${currUrl}".lower()
${expected} evaluate "${expected}".lower()
should contain ${currUrl} ${expected}