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".
Related
In RFC 3986, they defined the rule:
path-empty = 0<pchar>
For simplicity, let's assume pchar is defined:
pchar = 'a' / 'b' / 'c'
What does path-empty match and how is it matched?
I've read the Wikipedia page on ABNF. My guess is that matches the empty string (regex ^(?![\s\S])). If that is the case, why even reference pchar? Is there not a simpler way to match the empty string in ABNF syntax without referencing another rule?
How could this be translated to ANTLR4?
Yes, you are correct. path-empty derives the empty string.
In ABNF, the right-hand side of a rule must contain an element, which will be anything other than spaces, newlines, and comments. See rfc5234, page 10. Given this syntax, there are several ways to define the empty string. path-empty = 0<pchar> is one way. It means "exactly zero of <pchar>". But, path-empty = "" and path-empty = 0pchar would also work. ABNF does not define whether one is preferred over the other.
Note, the rfc3986 spec uses a prose-val, i.e., <pchar> instead of the "rulename" pchar (or even "", 0pchar, or just <empty string>). It's unclear why, but it has the same effect--path-empty derives the empty string. But, <pchar> is not the same as pchar. A prose value is a "last resort" way to add a non-formal description of the rule.
In Antlr4, the rule would just be path_empty : ;. Note, Antlr has a different naming convention that defines a strict boundary between lexer and parser. ABNF does not have this distinction. In fact, this grammar could be converted to a single Antlr lexer grammar, an exercise in understanding the power of Antlr lexers.
my lexical analyzer in flex can not recognize numbers and ids and operators ,only keywords were recognized where is my mistake? this is my code:
%{
#include<stdio.h>
%}
Nums [0-9]
LowerCase [a-z]
UpperCase [A-Z]
Letters LowerCase|UpperCase|[_]
Id {Letters}({Letters}|{Nums})*
operators +|-|\|*
%%
"if" {printf("if keyword founded \n");}
"then" {printf("then keyword founded \n");}
"else" {printf("else keyword founded \n");}
Operators {printf(" operator founded \n");}
Id {printf(" id founded ");}
%%
int main (void)
{ yylex(); return(0);}
int yywrap(void)
{ return 1;}
The pattern Operators is equivalent to "Operators", so it only matches that single word. If you meant to expand the macro by that name, the syntax is {Operators}. (Actually, {operators} since you seem to have inconsistently spelled the macro name in all lower-case.)
If you do that, flex will complain because of the syntax error in that macro. (Syntax errors in macros aren't detected unless the macro is expanded. That's just one of the problems with using macros.)
You have different problems with your other macros. For example, Nums doesn't appear in any rule at all.
My suggestion would be to use fewer (or no) macros and more character classes. Eg.:
[[:alpha:]_][[:alnum:]_]* { /* Action for identifier. */ }
[[:digit:]]+ { /* Action for number. */ }
[-+*/] { /* Action for operator. */ }
Please read the Patterns section in the flex manual for a full description of the pattern syntax, including the named character class expressions used in the first two patterns above.
To use a named definition, it ust be enclosed in {}. So your Letters rule should be
Letters {LowerCase}|{UpperCase}|[_]
... as it is, it matches the literal inputs LowerCase and UpperCase. Similarly in your rules, you want
{Operators} ...
{Id} ...
as what you have will match the literal input strings Operators and Id
I'm reading the PKCS #7 ASN.1 definition, and came across this type. I can't seem to find out what {{Authenticated}} is doing in this code, or what production this would be called. I've also seen as {{...}} in the PKCS #8 standard.
-- ATTRIBUTE information object class specification
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
}
Authenticated ATTRIBUTE ::= {
contentType |
messageDigest |
-- begin added for VCE SCEP-support
transactionID |
messageType |
pkiStatus |
failInfo |
senderNonce |
recipientNonce,
-- end added for VCE SCEP-support
..., -- add application-specific attributes here
signingTime
}
SignerInfoAuthenticatedAttributes ::= CHOICE {
aaSet [0] IMPLICIT SET OF AttributePKCS-7 {{Authenticated}},
aaSequence [2] EXPLICIT SEQUENCE OF AttributePKCS-7 {{Authenticated}}
-- Explicit because easier to compute digest on sequence of attributes and then reuse
-- encoded sequence in aaSequence.
}
-- Also defined in X.501
-- Redeclared here as a parameterized type
AttributePKCS-7 { ATTRIBUTE:IOSet } ::= SEQUENCE {
type ATTRIBUTE.&id({IOSet}),
values SET SIZE (1..MAX) OF ATTRIBUTE.&Type({IOSet}{#type})
}
-- Inlined from PKCS5v2-0 since it is the only thing imported from that module
-- AlgorithmIdentifier { ALGORITHM-IDENTIFIER:InfoObjectSet } ::=
AlgorithmIdentifier { TYPE-IDENTIFIER:InfoObjectSet } ::=
SEQUENCE {
-- algorithm ALGORITHM-IDENTIFIER.&id({InfoObjectSet}),
algorithm TYPE-IDENTIFIER.&id({InfoObjectSet}),
-- parameters ALGORITHM-IDENTIFIER.&Type({InfoObjectSet}
parameters TYPE-IDENTIFIER.&Type({InfoObjectSet}
{#algorithm}) OPTIONAL }
-- Private-key information syntax
PrivateKeyInfo ::= SEQUENCE {
version Version,
-- privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
privateKeyAlgorithm AlgorithmIdentifier {{...}},
privateKey PrivateKey,
attributes [0] Attributes OPTIONAL }
There is no ASN.1 item called double brace. Each single brace (even when nested) is a separate token. Since the definition of AttributePKCS-7 is not given here, I am guessing that it is likely a parametrized definition that takes an Information Object Set as the parameter. The outer pair of braces would be an indication of parameter substitution while the inner pair of braces indicates that Authenticated is an Information Object Set (which is used as the parameter). The purpose of the information object set is to restrict the possible values of certain fields to those contained in the object set. You will need to look at the definition of AttributePKCS-7 to see what components are being restricted by the object set.
As for the {{...}}, this is similar to the above except that the object set is an empty extensible object set (indicated by the {...}) which is being used as a parameter (indicated by the outer pair of braces).
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 ')')?;
Using F# in Visual Studio 2012, this code compiles:
let ``foo.bar`` = 5
But this code does not:
type ``foo.bar`` = class end
Invalid namespace, module, type or union case name
According to section 3.4 of the F# language specification:
Any sequence of characters that is enclosed in double-backtick marks (````),
excluding newlines, tabs, and double-backtick pairs themselves, is treated
as an identifier.
token ident =
| ident-text
| `` [^ '\n' '\r' '\t']+ | [^ '\n' '\r' '\t'] ``
Section 5 defines type as:
type :=
( type )
type -> type -- function type
type * ... * type -- tuple type
typar -- variable type
long-ident -- named type, such as int
long-ident<types> -- named type, such as list<int>
long-ident< > -- named type, such as IEnumerable< >
type long-ident -- named type, such as int list
type[ , ... , ] -- array type
type lazy -- lazy type
type typar-defns -- type with constraints
typar :> type -- variable type with subtype constraint
#type -- anonymous type with subtype constraint
... and Section 4.2 defines long-ident as:
long-ident := ident '.' ... '.' ident
As far as I can tell from the spec, types are named with long-idents, and long-idents can be idents. Since idents support double-backtick-quoted punctuation, it therefore seems like types should too.
So am I misreading the spec? Or is this a compiler bug?
It definitely looks like the specification is not synchronized with the actual implementation, so there is a bug on one side or the other.
When you use identifier in double backticks, the compiler treats it as a name and simply generates type (or member) with the name you specified in backticks. It does not do any name mangling to make sure that the identifier is valid type/member name.
This means that it is not too surprising that you cannot use identifiers that would clash with some standard meaning in the compiled code. In your example, it is dot, but here are a few other examples:
type ``Foo.Bar``() = // Dot is not allowed because it represents namespace
member x.Bar = 0
type ``Foo`1``() = // Single backtick is used to compile generic types
member x.Bar = 0
type ``Foo+Bar``() = // + is used in the name of a nested type
member x.Bar = 0
The above examples are not allowed as type names (because they clash with some standard meaning), but you can use them in let-bindings, because there are no such restrictions on variable names:
let ``foo`1`` = 0
let ``foo.bar`` = 2
let ``foo+bar`` = 1
This is definitely something that should be explained in the documentation & the specification, but I hope this helps to clarify what is going on.