Is there an easy way to have a in the final model a boolean field for a optional attribute AND a value assignment?
For example like this:
Enum:
name=ID assigned=( '(' value=INT ')' )?
;
My goal is to have an enum type similar to C where if you do not specify the enum value explicitly it will count from 0 or the last specified value.
I guess I need to compute the final values in a later step, but there I would need the information which of the values were given by the user.
Maybe there is even an easier solution to this...
Have a look at the ?= operator
Enum: name=ID (assigned?='(' value=INT ')')?;
Related
In the PKCS#9 standard they have the following assignment. The first line defines a type PrintableString, that can only two characters long, and must be one of the two letter country acronyms defined in ISO/IEC3166. The syntax used for defining this constraint is two separate constraints that follow one another, however looking at the ASN.1 standard, there can only be one "root" constraint. Is the syntax used in the PKCS#9 standard incorrect?
countryOfResidence ATTRIBUTE ::= {
WITH SYNTAX PrintableString (SIZE(2))(CONSTRAINED BY {
-- Must be a two-letter country acronym in accordance with
-- ISO/IEC 3166 --})
EQUALITY MATCHING RULE caseIgnoreMatch
ID pkcs-9-at-countryOfResidence
}
ATTRIBUTE ::= CLASS {
&derivation ATTRIBUTE OPTIONAL,
&Type OPTIONAL, -- either &Type or &derivation required
&equality-match MATCHING-RULE OPTIONAL,
&ordering-match MATCHING-RULE OPTIONAL,
&substrings-match MATCHING-RULE OPTIONAL,
&single-valued BOOLEAN DEFAULT FALSE,
&collective BOOLEAN DEFAULT FALSE,
&dummy BOOLEAN DEFAULT FALSE,
-- operational extensions
&no-user-modification BOOLEAN DEFAULT FALSE,
&usage AttributeUsage DEFAULT userApplications,
&id OBJECT IDENTIFIER UNIQUE
}
WITH SYNTAX {
[SUBTYPE OF &derivation]
[WITH SYNTAX &Type]
[EQUALITY MATCHING RULE &equality-match]
[ORDERING MATCHING RULE &ordering-match]
[SUBSTRINGS MATCHING RULE &substrings-match]
[SINGLE VALUE &single-valued]
[COLLECTIVE &collective]
[DUMMY &dummy]
[NO USER MODIFICATION &no-user-modification]
[USAGE &usage]
ID &id
}
ASN.1 Production (Found in ISO/IEC 8824-1:2015 / Rec. ITU-T X.680 (08/2015) page. 87)
ConstrainedType ::=
Type Constraint
| TypeWithConstraint
Constraint ::= "(" ConstraintSpec ExceptionSpec ")"
ConstraintSpec ::=
SubtypeConstraint
| GeneralConstraint
Constraints can be serially applied. It is legitimate. The "Type" that you are adding a constraint to can itself be a "ConstrainedType".
Say I have a scope like this:
scope :by_templates, ->(t) { joins(:template).where('templates.label ~* ?', t) }
How can I retrieve multiple templates with t like so?
Document.first.by_templates(%w[email facebook])
This code returns this error.
PG::DatatypeMismatch: ERROR: argument of AND must be type boolean, not type record
LINE 1: ...template_id" WHERE "documents"."user_id" = $1 AND (templates...
PostgreSQL allows you to apply a boolean valued operator to an entire array of values using the op any(array_expr) construct:
9.23.3. ANY/SOME (array)
expression operator ANY (array expression)
expression operator SOME (array expression)
The right-hand side is a parenthesized expression, which must yield an array value. The left-hand expression is evaluated and compared to each element of the array using the given operator, which must yield a Boolean result. The result of ANY is “true” if any true result is obtained. The result is “false” if no true result is found (including the case where the array has zero elements).
PostgreSQL also supports the array constructor syntax for creating arrays:
array[value, value, ...]
Conveniently, ActiveRecord will expand a placeholder as a comma-delimited list when the value is an array.
Putting these together gives us:
scope :by_templates, ->(templates) { joins(:template).where('templates.label ~* any(array[?])', templates) }
As an aside, if you're using the case-insensitive regex operator (~*) as a case-insensitive comparison (i.e. no real regex pattern matching going on) then you might want to use upper instead:
# Yes, this class method is still a scope.
def self.by_templates(templates)
joins(:template).where('upper(templates.label) = any(array[?])', templates.map(&:upcase) }
end
Then you could add an index to templates on upper(label) to speed things up and avoid possible issues with stray regex metacharacters in the templates. I tend to use upper case for this sort of thing because of oddities lie 'ß'.upcase being 'SS' but 'SS'.downcase being 'ss'.
I have a section of a ALTLR grammar which goes like this:
mainfilter: mandatoryfilter (optionalfilter1)? (optionalfilter2)? (optionalfilter3)? ;
mandatoryfilter: 'NAME' '=' ID;
optionalfilter1: 'VALUE1' EQ ID;
optionalfilter2: 'VALUE2' EQ ID;
optionalfilter3: 'VALUE3' EQ ID;
EQ: '=' ;
ID: [A-Za-z0-9]+
//Also I will skip spaces and whitespace
My requirement is that the "optionalfilter" rules can occur in any order.
One approach I think of is rewrite the rule like below and then validate using a Listener:
mainfilter: mandatoryfilter (optionalfilter1|optionalfilter2|optionalfilter3)*;
Another way to achieve this is to put all combinations in one parser rule each . but that may not be a wiser solution if the number of optionalfilter increases.
Sample input:
NAME = BOB VALUE1=X VALUE2=Y VALUE3 = Z
NAME = BILL VALUE3=X VALUE1=Y VALUE2 = Z
my grammar will successfully parse the first input but not the second one.
So is there an elegant way to handle this in my grammar itself ?
So is there an elegant way to handle this in my grammar itself ?
No.
Usually, zero or more are matched and then after parsing, it is validated that a filter only occurs once.
Take for example the Java Language Specification that defines that a class definition can have zero or more class modifiers (the {ClassModifier} part)
NormalClassDeclaration:
{ClassModifier} class Identifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody
ClassModifier:
(one of)
Annotation public protected private abstract static final strictfp
which would match public public class Foo {}. This is rejected at the stage after parsing.
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;
Code taken from ply.lex documentation: http://www.dabeaz.com/ply/ply.html#ply_nn6
reserved = {
'if' : 'IF',
'then' : 'THEN',
'else' : 'ELSE',
'while' : 'WHILE',
...
}
tokens = ['LPAREN','RPAREN',...,'ID'] + list(reserved.values())
def t_ID(t):
r'[a-zA-Z_][a-zA-Z_0-9]*'
t.type = reserved.get(t.value,'ID') # Check for reserved words
return t
For the reserved words, we need to change the token type. Doing reserved.get() by passing to it the t.value is understandable. Now it should return the entities in the second column in the reserved specification.
But why are we passing to it ID? What does it mean and what purpose does it solve?
The second parameter specifies the value to return should the key not exist in the dictionary. So in this case, if the value of t.value does not exist as a key in the reserved dictionary, the string 'ID' will be returned instead.
In other words, a.get(b, c) when a is a dict is roughly equivalent to a[b] if b in a else c (except it is presumably more efficient, as it would only look up the key once in the success case).
See the Python documentation for dict.get().