What does noautovalidity mean on a struct member definition in the Vulkan API schema (vk.xml)?
registry.rnc says tag stating that no automatic validity language should be generated
The Vulkan registry spec says: prevents automatic validity language being generated for the tagged item. Only suppresses item-specific validity - parenting issues etc. are still captured. It must also be used for structures that have no implicit validity when such structure has explicit validity.
What is automatic validity language?
What is an example of something that has noautovalidity, and of that example, what was the item-specific validity that is suppressed? and why was it decided to be suppressed?
Consult the XML schema doc.
noautovalidity means most Valid Usage (Implicit) entries will not be generated for a given parameter or structure member.
It may mean Implicit Validity rules do not apply to the given item, although many times very similar Explicit VU is given in its place.
Examples:
VkWriteDescriptorSet::pImageInfo has noautovalidity because it shares descriptorCount. It prevents generating something like "pImageInfo has to be an array of descriptorCount elements". Instead Explicit VU is given, e.g.: "If descriptorType is *_IMAGE, then pImageInfo has to be an array of descriptorCount elements`.
VkComputePipelineCreateInfo::basePipelineHandle is noautovalidity because the API allows the parameter to be ignored if flags does not contain VK_PIPELINE_CREATE_DERIVATIVE_BIT. Without the attribute the spec would insist the handle has to be a valid VkPipeline (or additionally allowed to be VK_NULL_HANDLE if optional).
Corner case example:
VkViewport::x is noautovalidity. It does not seemingly need noautovalidity, but in this case it signifies that although the struct has no Implicit Validity, some Explicit Validity may be present in the spec.
Related
From the docs that say,
Returns the self-reference to the instance itself:
my $b; # defaults to Any
say $b.serial.^name; # OUTPUT: «Any»
my $breakfast = 'food';
$breakfast.serial.say; # OUTPUT: «food»
I do not have the foggiest what this routine does, please can someone explain?
On Supplys, it is an informational method that is supposed to indicate whether there will never be any concurrent emit on that Supply.
On HyperSeq and RaceSeq, it returns a serialized Seq, so you could consider it the opposite of the hyper and race method.
In general, it appears to return itself, which seems to make sense from the HyperSeq and RaceSeq point of view.
And yes, these should be documented properly, so please create a documentation issue. Thank you!
In the doc example it does nothing. That is, if you remove it you get the same results:
my $b; # defaults to Any
say $b.^name; # OUTPUT: «Any»
my $breakfast = 'food';
$breakfast.say; # OUTPUT: «food»
More generally, I think you'd best ignore the serial method other than to open a doc issue pointing to this SO if you'd like to improve the doc.
The serial method does not appear to be in the official language
A search of the roast repo for "serial" yields zero matches.
Within Rakudo source code the method name serial has been overloaded to have one of three meanings:
A boolean declaring whether a Supply sequence is always serial. Rakudo source examples: 1, 2. This looks to me like an internal method that doesn't need to be documented.
A coercion of parallel sequence (hyper or race) to a serial version of the same sequence. This looks to me like an internal method that doesn't need to be documented.
A "no op" that returns its invocant. I suspect it would be best if it were not documented, at least until such time as its raison d'etre is clear; its official status viz-a-viz the spec (roast) is clear; and/or there's an attempt to systematically document which operations have the is nodal set on them.
None of the above seems to warrant ordinary users' attention or documentation.
The Any class definition of a serial method seems pointless
The Any class serial method returns self, i.e. when called it is a no op.
I don't currently understand why there is an Any class definition.
One possible point for it would be that there are .serial calls made by internal code on instances of an unknown and generally unknowable class and there thus needs to be a default definition of serial in the Any class.
But a search of the rakudo repo for ".serial" suggests that calls are only made to supplies or hyper/race seqs.
That said, I note the is nodal trait on the proto serial declaration in Any that immediately precedes the multi method serial declaration. Perhaps that is the reason it's in Any.
See also Arbitrary drift of methods to Mu and Any.
The documentation you quoted seems pointless
The definition and example seem to reflect someone's sense of humor. I applaud use of humor but in this case I suspect the best improvement would be to just remove the page you linked.
We are writing a tool in Java that parses and transforms ABAP code. We therefore have no intention to write new ABAP code but our tool has to handle all of ABAP, even obsolete statements. Furthermore, I'm not an ABAP expert.
ABAP programs can use type groups, introduced by key word TYPE-POOL. Names of type groups have a maximal length of five (internally eight, if you count the prefix "% C"), their type code is TYPP. In the past, relying on these assumptions worked well for us.
Recently, we see ABAP programs with type code TYPP but with name longer than 5, e.g., 'OIA===========================P'. Furthermore, for each of those, there is another, empty object with same name but type code INCL. These new objects are referenced only if a regular type group is, too.
These new objects may be internal ones and irrelevant for us - I haven't seen any reference to them in the ABAP Keyword Documentation. On the other hand, they are confusing us because we see them.
Can someone explain to me the meaning of these objects and point me to some documentation?
Edit: Here examples from an EHP7 for SAP ERP 6.0 system
An example object. Entries in D010INC look fine:
The same object now using type pool mrm. Where do the additional includes come from?
These objects are introduced through inclusions, extensions and switched objects. To read along:
Check type pool MRM, type mrm_idoc_data_ers - that type contains a statement to include rmrm_idoc_data_ers_sbo. A similar include statement pulls rmrm_upd_arseg_nfm into mrm_upd_arseg. That explains the last two lines. Your parser should have caught that.
RMRM_IDOC_DATA_ERS_SBO contains an enhancement point named RMRM_IDOC_DATA_ERS_SBO_02 that belongs to an enhancement spot ES_RMRM_IDOC_DATA_ERS_SBO. Similarly, RMRM_UPD_ARSEG_NFM contains an enhancement point RMRM_UPD_ARSEG_NFM_01 that belongs to the enhancement spot ES_RMRM_UPD_ARSEG_NFM.
For ES_RMRM_IDOC_DATA_ERS_SBO, an enhancement implementation named ISAUTO_MRM_RMRM_IDOC_DATA_ERS exists. For ES_RMRM_UPD_ARSEG_NFM, an implementation named /NFM/MM_RMRM_UPD_ARSEG_NFM exists. That explains the references ending with =E
The implementation ISAUTO_MRM_RMRM_IDOC_DATA_ERS is located in the package ISAUTO_MRM. The implementation /NFM/MM_RMRM_UPD_ARSEG_NFM is located in the package /NFM/MM. That explains the references ending with =P. Obviously, these references are not generated for every package:
The package ISAUTO_MRM is controlled by the switch AM_ERS, the package /NFM/MM is controlled by the switch /NFM/MM. That explains the references ending in =S.
Ultimately, these references can be used to determine which programs need to be re-generated when the state of a switch is changed.
I am trying to figure out how yacc identifies function calls in a C code. For Example: if there is a function call like my_fun(a,b); then which rules does this statement reduces to.
I am using the cGrammar present in : C Grammar
Following the Grammar given over there manually; I figured out that we only have two choices in translation unit. Everything has to either be a function definition or a declaration. Now all declaration starts type_specifiers, storage_class_specifier etc but none of them starts with IDENTIFIER
Now in case of a function call the name would be IDENTIFIER. This leaves me unclear as to how it will be parsed and which rules will be used exactly?
According to the official yacc specification specified here yacc, everything is handled by user given routines. When you have a function call the name of course is IDENTIFIER.It is parsed using the user defined procedures.According to the specifications, the user can specify his input in terms of individual input characters, or in terms of higher level constructs such as names and numbers. The user-supplied routine may also handle idiomatic features such as comment and continuation conventions, which typically defy easy grammatical specification.
Do have a look.By the way you are supposed to do a thorough research before putting questions here.
I am wondering if there exists already some naming conventions for Ocaml, especially for names of constructors, names of variables, names of functions, and names for labels of record.
For instance, if I want to define a type condition, do you suggest to annote its constructors explicitly (for example Condition_None) so as to know directly it is a constructor of condition?
Also how would you name a variable of this type? c or a_condition? I always hesitate to use a, an or the.
To declare a function, is it necessary to give it a name which allows to infer the types of arguments from its name, for example remove_condition_from_list: condition -> condition list -> condition list?
In addition, I use record a lot in my programs. How do you name a record so that it looks different from a normal variable?
There are really thousands of ways to name something, I would like to find a conventional one with a good taste, stick to it, so that I do not need to think before naming. This is an open discussion, any suggestion will be welcome. Thank you!
You may be interested in the Caml programming guidelines. They cover variable naming, but do not answer your precise questions.
Regarding constructor namespacing : in theory, you should be able to use modules as namespaces rather than adding prefixes to your constructor names. You could have, say, a Constructor module and use Constructor.None to avoid confusion with the standard None constructor of the option type. You could then use open or the local open syntax of ocaml 3.12, or use module aliasing module C = Constructor then C.None when useful, to avoid long names.
In practice, people still tend to use a short prefix, such as the first letter of the type name capitalized, CNone, to avoid any confusion when you manipulate two modules with the same constructor names; this often happen, for example, when you are writing a compiler and have several passes manipulating different AST types with similar types: after-parsing Let form, after-typing Let form, etc.
Regarding your second question, I would favor concision. Inference mean the type information can most of the time stay implicit, you don't need to enforce explicit annotation in your naming conventions. It will often be obvious from the context -- or unimportant -- what types are manipulated, eg. remove cond (l1 # l2). It's even less useful if your remove value is defined inside a Condition submodule.
Edit: record labels have the same scoping behavior than sum type constructors. If you have defined a {x: int; y : int} record in a Coord submodule, you access fields with foo.Coord.x outside the module, or with an alias foo.C.x, or Coord.(foo.x) using the "local open" feature of 3.12. That's basically the same thing as sum constructors.
Before 3.12, you had to write that module on each field of a record, eg. {Coord.x = 2; Coord.y = 3}. Since 3.12 you can just qualify the first field: {Coord.x = 2; y = 3}. This also works in pattern position.
If you want naming convention suggestions, look at the standard library. Beyond that you'll find many people with their own naming conventions, and it's up to you to decide who to trust (just be consistent, i.e. pick one, not many). The standard library is the only thing that's shared by all Ocaml programmers.
Often you would define a single type, or a single bunch of closely related types, in a module. So rather than having a type called condition, you'd have a module called Condition with a type t. (You should give your module some other name though, because there is already a module called Condition in the standard library!). A function to remove a condition from a list would be Condition.remove_from_list or ConditionList.remove. See for example the modules List, Array, Hashtbl,Map.Make`, etc. in the standard library.
For an example of a module that defines many types, look at Unix. This is a bit of a special case because the names are mostly taken from the preexisting C API. Many constructors have a short prefix, e.g. O_ for open_flag, SEEK_ for seek_command, etc.; this is a reasonable convention.
There's no reason to encode the type of a variable in its name. The compiler won't use the name to deduce the type. If the type of a variable isn't clear to a casual reader from the context, put a type annotation when you define it; that way the information provided to the reader is validated by the compiler.
I'm having a hard time understanding what I'm supposed to do. The only thing I've figured out is I need to use yacc on the cminus.y file. I'm totally confused about everything after that. Can someone explain this to me differently so that I can understand what I need to do?
INTRODUCTION:
We will use lex/flex and yacc/Bison to generate an LALR parser. I will give you a file called cminus.y. This is a yacc format grammar file for a simple C-like language called C-minus, from the book Compiler Construction by Kenneth C. Louden. I think the grammar should be fairly obvious.
The Yahoo group has links to several descriptions of how to use yacc. Now that you know flex it should be fairly easy to learn yacc. The only base type is int. An int is 4 bytes. Booleans are handled as ints, as in C. (Actually the grammar allows you to declare a variable as a type void, but let's not do that.) You can have one-dimensional arrays.
There are no pointers, but references to array elements should be treated as pointers (as in C).
The language provides for assignment, IF-ELSE, WHILE, and function calls and returns.
We want our compiler to output MIPS assembly code, and then we will be able to run it on SPIM. For a simple compiler like this with no optimization, an IR should not be necessary. We can output assembly code directly in one pass. However, our first step is to generate a symbol table.
SYMBOL TABLE:
I like Dr. Barrett’s approach here, which uses a lot of pointers to handle objects of different types. In essence the elements of the symbol table are identifier, type and pointer to an attribute object. The structure of the attribute object will differ according to the type. We only have a small number of types to deal with. I suggest using a linear search to find symbols in the table, at least to start. You can change it to hashing later if you want better performance. (If you want to keep in C, you can do dynamic allocation of objects using malloc.)
First you need to make a list of all the different types of symbols that there are—there are not many—and what attributes would be necessary for each. Be sure to allow for new attributes to be added, because we
have not covered all the issues yet. Looking at the grammar, the question of parameter lists for functions is a place where some thought needs to be put into the design. I suggest more symbol table entries and pointers.
TESTING:
The grammar is correct, so taking the existing grammar as it is and generating a parser, the parser will accept a correct C-minus program but it won’t produce any output, because there are no code snippets associated with the rules.
We want to add code snippets to build the symbol table and print information as it does so.
When an identifier is declared, you should print the information being entered into the symbol table. If a previous declaration of the same symbol in the same scope is found, an error message should be printed.
When an identifier is referenced, you should look it up in the table to make sure it is there. An error message should be printed if it has not been declared in the current scope.
When closing a scope, warnings should be generated for unreferenced identifiers.
Your test input should be a correctly formed C-minus program, but at this point nothing much will happen on most of the production rules.
SCOPING:
The most basic approach has a global scope and a scope for each function declared.
The language allows declarations within any compound statement, i.e. scope nesting. Implementing this will require some kind of scope numbering or stacking scheme. (Stacking works best for a one-pass
compiler, which is what we are building.)
(disclaimer) I don't have much experience with compiler classes (as in school courses on compilers) but here's what I understand:
1) You need to use the tools mentioned to create a parser which, when given input will tell the user if the input is a correct program as to the grammar defined in cminus.y. I've never used yacc/bison so I don't know how it is done, but this is what seems to be done:
(input) file-of-some-sort which represents output to be parsed
(output) reply-of-some-sort which tells if the (input) is correct with respect to the provided grammar.
2) It also seems that the output needs to check for variable consistency (ie, you can't use a variable you haven't declared same as any programming language), which is done via a symbol table. In short, every time something is declared you add it to the symbol table. When you encounter an identifier, if it is not one of the language identifiers (like if or while or for), you'll look it up in the symbol table to determine if it has been declared. If it is there, go on. If it's not - print some-sort-of-error
Note: point(2) there is a simplified take on a symbol table; in reality there's more to them than I just wrote but that should get you started.
I'd start with yacc examples - see what yacc can do and how it does it. I guess there must be some big example-complete-with-symbol-table out there which you can read to understand further.
Example:
Let's take input A:
int main()
{
int a;
a = 5;
return 0;
}
And input B:
int main()
{
int a;
b = 5;
return 0;
}
and assume we're using C syntax for parsing. Your parser should deem Input A all right, but should yell "b is undeclared" for Input B.