Can't use IF NOT with a set in delphi - delphi

I have a set of chars which I define in the TYPE section as:
TAmpls = set of '1'..'9'';
In my function I declare a new variable, in the var section, with type Tampls using:
myAmpls : Tampls;
I then un-assign everything in myAmpls using:
myAMpls := [];
I then find an integer (I'll call it n). If this number is not assigned in my set variable, I want to assign it, for this I have tried using:
if not chr(n) in myAmpls then include(myAmpls,chr(n));
But the compiler throws an error saying:
'Operator not applicable to this operand type'
If I remove the 'not', the code compiles fine, why is this?
I would have thought that whether or not n was already in myAmpls was boolean, so why can't I use 'not'?

Delphi operator precedence is detailed in the documentation. There you will find a table of the operators listing their precedence. I won't reproduce the table here, no least because it's hard to lay out in markdown!
You will also find this text:
An operator with higher precedence is evaluated before an operator with lower precedence, while operators of equal precedence associate to the left.
Your expression is:
not chr(n) in myAmpls
Now, not has higher precedence than in. Which means that not is evaluated first. So the expression is parsed as
(not chr(n)) in myAmpls
And that is a syntax error because not cannot be used with a character operand. You need to apply parens to give the desired meaning to your expression:
not (chr(n) in myAmpls)

Related

why we need both Look Ahead symbol and read ahead symbol in Compiler

well i was reading some common concepts regarding parsing in compiler..i came across look ahead and read ahead symbol i search and read about them but i am stuck like why we need both of them ? would be grateful for any kind suggestion
Lookahead symbol: when node being considered in parse tree is for a terminal, and the
terminal matches lookahead symbol,then we advance in both parse and
input
read aheadsymbol: lexical analyzer may need to read some character
before it can decide on the token to be returned
One of these is about parsing and refers to the next token to be produced by the lexical scanner. The other one, which is less formal, is about lexical analysis and refers to the next character in the input stream. It should be clear which is which.
Note that while most parsers only require a single lookahead token, it is not uncommon for lexical analysis to have to backtrack, which is equivalent to examining several unconsumed input characters.
I hope I got your question right.
Consider C.
It has several punctuators that begin the same way:
+, ++, +=
-, --, -=, ->
<, <=, <<, <<=
...
In order to figure out which one it is when you see the first + or - or <, you need to look ahead one character in the input (and then maybe one more for <<=).
A similar thing can happen at a higher level:
{
ident1 ident2;
ident3;
ident4:;
}
Here ident1, ident3 and ident4 can begin a declaration, an expression or a label. You can't tell which one immediately. You can consult your existing declarations to see if ident1 or ident3 is already known (as a type or variable/function/enumeration), but it's still ambiguous because a colon may follow and if it does, it's a label because it's permitted to use the same identifier for both a label and a type/variable/function/enumeration (those two name spaces do not intersect), e.g.:
{
typedef int ident1;
ident1 ident2; // same as int ident2
int ident3 = 0;
ident3; // unused expression of value 0
ident1:; // unused label
ident2:; // unused label
ident3:; // unused label
}
So, you may very well need to look ahead a character or a token (or "unread" one) to deal with situations like these.

Ada vector of enumerated type

I am trying to created a vector of an enumerated type in Ada, but the compiler seems to expect an equality function overload. How do I telll the compiler to just use the default equal function. Here's what I have:
package HoursWorkedVector is new Ada.Containers.Vectors(Natural,DAY_OF_WEEK);
--where Day of week is defined as an enumeration
When I try to compile, I get the message:
no visible subprogram matches the specification for "="
Do I need to create a comparison function to have a vector of an enumerated type? Thanks in advance.
The definition of Ada.Containers.Vectors starts like this:
generic
type Index_Type is range <>;
type Element_Type is private;
with function "=" (Left, Right : Element_Type)
return Boolean is <>;
package Ada.Containers.Vectors is
The meaning of <> in a generic formal function is defined by RM 12.6(10):
If a generic unit has a subprogram_default specified by a box, and the
corresponding actual parameter is omitted, then it is equivalent to an
explicit actual parameter that is a usage name identical to the
defining name of the formal.
So if, as you said in the comments, DAY_OF_WEEK is defined in another package, your instantiation is equivalent to
package HoursWorkedVector is new Ada.Containers.Vectors(Natural, Other_Package.DAY_OF_WEEK, "=");
which doesn't work because the "=" that compares DAY_OF_WEEK values is not visible.
You can include Other_Package."=" in the instantiation, as suggested in a comment. There are at least three ways to make "=" visible, so that your original instantiation would work:
use Other_Package; This will make "=" directly visible, but it will also make everything else defined in that package directly visible. This may not be what you want.
use type Other_Package.DAY_OF_WEEK; This makes all the operators of DAY_OF_WEEK directly visible, including "<", "<=", etc., as well as all the enumeration literals, and any other primitive subprograms of DAY_OF_WEEK that you may have declared in Other_Package. This is probably the favorite solution, unless for some reason it would be a problem to make the enumeration literals visible.
Use a renaming declaration to redefine "=":
function "=" (Left, Right : DAY_OF_WEEK) return Boolean
renames Other_Package."=";
This makes "=" directly visible.
The compiler automatically selects the predefined equality operator:
with
Ada.Containers.Vectors;
package Solution is
type Day_Of_Week is (Work_Day, Holiday);
package Hours_Worked_Vector is
new Ada.Containers.Vectors (Index_Type => Natural,
Element_Type => Day_Of_Week);
end Solution;

Why are redundant parenthesis not allowed in syntax definitions?

This syntax module is syntactically valid:
module mod1
syntax Empty =
;
And so is this one, which should be an equivalent grammar to the previous one:
module mod2
syntax Empty =
( )
;
(The resulting parser accepts only empty strings.)
Which means that you can make grammars such as this one:
module mod3
syntax EmptyOrKitchen =
( ) | "kitchen"
;
But, the following is not allowed (nested parenthesis):
module mod4
syntax Empty =
(( ))
;
I would have guessed that redundant parenthesis are allowed, since they are allowed in things like expressions, e.g. ((2)) + 2.
This problem came up when working with the data types for internal representation of rascal syntax definitions. The following code will create the same module as in the last example, namely mod4 (modulo some whitespace):
import Grammar;
import lang::rascal::format::Grammar;
str sm1 = definition2rascal(\definition("unknown_main",("the-module":\module("unknown",{},{},grammar({sort("Empty")},(sort("Empty"):prod(sort("Empty"),[
alt({seq([])})
],{})))))));
The problematic part of the data is on its own line - alt({seq([])}). If this code is changed to seq([]), then you get the same syntax module as mod2. If you further delete this whole expression, i.e. so that you get this:
str sm3 =
definition2rascal(\definition("unknown_main",("the-module":\module("unknown",{},{},grammar({sort("Empty")},(sort("Empty"):prod(sort("Empty"),[
], {})))))));
Then you get mod1.
So should such redundant parenthesis by printed by the definition2rascal(...) function? And should it matter with regards to making the resulting module valid or not?
Why they are not allowed is basically we wanted to see if we could do without. There is currently no priority relation between the symbol kinds, so in general there is no need to have a bracket syntax (like you do need to + and * in expressions).
Already the brackets have two different semantics, one () being the epsilon symbol and two (Sym1 Sym2 ...) being a nested sequence. This nested sequence is defined (syntactically) to expect at least two symbols. Now we could without ambiguity introduce a third semantics for the brackets with a single symbol or relax the requirement for sequence... But we reckoned it would be confusing that in one case you would get an extra layer in the resulting parse tree (sequence), while in the other case you would not (ignored superfluous bracket).
More detailed wise, the problem of printing seq([]) is not so much a problem of the meta syntax but rather that the backing abstract notation is more relaxed than the concrete notation (i.e. it is a bigger language or an over-approximation). The parser generator will generate a working parser for seq([]). But, there is no Rascal notation for an empty sequence and I guess the pretty printer should throw an exception.

High-precedence application expressions as arguments

A high precedence application expression is one in which an identifier is immediately following by a left paren without intervening whitespace, e.g., f(g). Parentheses are required when passing these as function arguments: func (f(g)).
Section 15.2 of the spec states the grammar and precedence rules allow the unparenthesized form -- func f(g) -- but an additional check prevents this.
Why is this intentionally prohibited? It would obviate the need for excessive parentheses and piping, and generally make the code much cleaner.
A common example is
raise <| IndexOutOfRangeException()
or
raise (IndexOutOfRangeException())
could become simply
raise IndexOutOfRangeException()
I agree that the need for writing the additional parentheses is a bit annoying. I think that the main reason why it is not allowed to omit them is that adding a whitespace would then change the meaning of your code in quite a significant way:
// Call 'foo' with the result of 'bar()' as an argument
foo bar()
// Call 'foo' with 'bar' as the first argument and '()' as the second
foo bar ()
There are still some rough edges where adding parens changes the evaluation (see this form post), but that "just" changes the evaluation order. This would change the meaning of your code!

node label/key in XText when translating from grako

In grako one can use the following name:e to add the result of e to the AST using name as key. For example
var_def
=
var+:ID {',' var+:ID}*
What would be a good translation of this to Xtext?
I tried
var_def:
var=ID (',' var=ID)*;
which is not failing, but is raising the following warning
Multiple markers at this line
- The possibly assigned value of feature 'var' may be overridden
by subsequent assignments.
- This assignment will override the possibly assigned value of
feature 'var'.
I think I am trying to mimic the name behavior, but do not have much success.
With your solution only the last ID will be available in the AST. I assume var should be a multi-valued feature holding all IDs, not only the last one. This can be expressed as
var_def:
var+=ID (',' var+=ID)*;
In the resulting AST var is a list of IDs.

Resources