In this thread the meaning of the # symbol is explained:
What does the '#' symbol mean in Swift?
In the thread # is said to identify an attribute. But there's another statement saying it's a "compiler directive". I've also learned that the Objective-C like Swift statement:
#autoreleasepool {...} nowdays can be used without the # symbol.
So this leaves me quite puzzled. What is the actual meaning of the # symbol itself? It seems to me it can be used for more than attributes but I've found no document explaining the exact rules for how to use #. Mostly I find examples on how to use it as an attribute.
Or is it that the language has changed lately and nowdays, with Swift 4, # is for attributes only?
EDIT: Since I had remarks I should not ask about Swift and Objective C in the same thread I've edited the text to focus on Swift.
Related
I don't need typedef's exactly. I need aliases (for a shell language). But the hack of looking up an identifier and returning a different token type is what I need to make the grammar work. I don't necessarily need it to be done in the lexer, although that would seem cleanest to me (or in a phase between the lexer and parser).
Here is (a fragment of) the closest I can seem to come to a solution given what I know of antlr4, but it requires a whole level of non-terminals for each keyword token. Note, that per Antlr4 Capitalized words or tokens, lower case words are non-terminals.
aliasstmt: alias ident ident; // rule that makes aliases
ifstmt: if expression then statement; // sample rule with two keywords
// non-terminals converting aliases into keywords
alias: Alias // normal token for keyword
// hack, LookupAlias is map, I need.
| { LookupAlias(_input.LT(1).getText()).equals("alias") }? Ident
;
if : If
| { LookupAlias(_input.LT(1).getText()).equals("if") }? Ident
;
then : Then
| { LookupAlias(_input.LT(1).getText()).equals("then") }? Ident
;
// Non-terminal going the other way, converting keywords to identifiers when needed
ident : Ident
| Alias
| If
| Then
;
Now, I suppose, I could get rid of the Tokens for the keywords and do it all in the parser for this example. It wouldn't completely work in the language I'm parsing because a significant number of the keywords have "normal" spellings like "Set-Alias" or "-Name" which are not legal identifiers (and "Set - Alias" or "Set -Alias" is not the same as "Set-Alias", uggh).
However, I want to LookupAlias() function to be it's own Java class not something just embedded in the parser. I have other times I need to us it that aren't part of parsing and those times need to have then coordinated. How to do that is a separate question I will ask.
(Caveat... maybe aliases can be used in a shell in places I don’t know about, so this is based on my understanding)
In a shell, an alias is essentially an identifier that is expanded when it’s encountered. It’s only expected where a command could occur, and since you can’t know all the command in the path, your grammar would likely have an IDENTIFIER token (or the like) at that location in the parser rule.
You’d then check it against a list of built-in commands, commands in your PATH, and aliases (I’m not sure of the precedence, TBH).
So, you’d need to keep a symbol table to look up the alias resolution. I think post-resolution is where things will get “tricky”. IIRC, aliases don’t have to be syntactically complete, you you couldn’t really expect to pre-parse them (they possibly won’t parse correctly). Also, they are pretty much “injected” into the input stream. In this way they’re much more like pre-processor macros. I don’t see much way around detecting them, building an expanded input stream and lexing/parsing it.
I suppose that you could write a custom TokenStream, that detected aliases and responded to getNextToken() (and methods to get the token at a particular index, etc.). That would allow aliases anywhere in the token stream, which could get weird, and it would be the devil, probably, to provide useful error messages. (I guess you’d just have to point them at the alias itself). This approach would supply the alias definition tokens in place of the alias as the parser asked for the next token. I don’t see a way that you’ll use actions/predicates to change ANTLRs mind about what token it just saw :).
I suspect playing with existing shells a bit, creating invalid alias substitutions into the command line, and observing the error messages, might give insight into how other shells handle it. My impression, is that the shell preprocess the input and substitutes things like aliases and ENV variables, etc. and then re-parses the result the result for execution.
I’m pretty sure trying to modify the tokenStream as the parser is already processing it, is either no doable, or the path to madness.
I cannot understand where lazy-static's #TAIL and #MAKE have been defined and their particular use cases.
If I've understood internal rules correctly, the primary usage of #as_expr in the example is to hide as_expr! (or in general, previously defined macros) from being exported i.e. it's a way of altering the global macro namespace. Following that, then #TAIL or #MAKE should already be a macro while I cannot find them in the lazy_static source.
You linked to the definitions. #TAIL is right there three lines down on 137, #MAKE is on 162.
#name is not special in any way whatsoever. There is absolutely no special behaviour. It's just a sequence of tokens that cannot show up in "normal" code, and is thus unlikely to be accidentally matched to other rules. #as_expr does not hide an as_expr! macro, it's used instead of defining a publicly visible as_expr! macro.
I'm trying to figure out how to modify an XML file with NSIS. So I'm trying to learn how to use the XML plugin. The examples on the forum page often use the format ${plugin::command} like:
${xml::LoadFile}
The documentation gives no indication that you need the dollar sign and curly braces. As I understand it, just plugin::command will do. So I've been trying to figure out what that syntax means.
The documentation says a $ is for variables and the {} are for code blocks, but I can't find anything about what it means when they're used together. My Internet searches have revealed that it's used for something called template literals in JavaScript. But what does it mean in NSIS?
EDIT: I should mention that the NSIS documentation does show examples of this syntax, especially in the Predefines section, but it still doesn't explain what the syntax means in general.
EDIT: Okay, now I see that the syntax is for the compiler to replace things using !define and !macro. But... what about this specific case? Is it valid to use colons in such a symbol? Why are some people writing ${xml::LoadFile}and some people just writing xml::LoadFile?
It's a !define. There is a header file for this plugin that defines it. The plugin probably needs to do more than one thing, so they wrapped a few lines together with a define that inserts a macro. Either that or it has some default parameters for the plugin call. Either way, it's trying to save you some typing with this syntax.
I'm learning about gcc's cleanup attribute, and learning how it calls a function to be run when a variable goes out of scope, and I don't understand why you can use the word "cleanup" with or without underscores. Where is the documentation for, or documentation of, the version with underscores?
The gcc documentation above shows it like this:
__attribute__ ((cleanup(cleanup_function)))
However, most code samples I read, show it like this:
__attribute__ ((__cleanup__(cleanup_function)))
Ex:
http://echorand.me/site/notes/articles/c_cleanup/cleanup_attribute_c.html
http://www.nongnu.org/avr-libc/user-manual/atomic_8h_source.html
Note that the first example link states they are identical, and of course coding it proves this, but how did he know this originally? Where did this come from?
Why the difference? Where is __cleanup__ defined or documented, as opposed to cleanup?
My fundamental problem lies in the fact that I don't know what I don't know, therefore I am trying to expose some of my unknown unknowns so they become known unknowns, until I can study them and make them known knowns.
My thinking is that perhaps there is some globally-applied principle to gcc preprocessor directives, where you can arbitrarily add underscores before or after any of them? -- Or perhaps only some of them? -- Or perhaps it modifies the preprocessor directive or attribute somehow and there are cases where one method, with or without the extra underscores, is preferred over the other?
You are allowed to define a macro cleanup, as it is not a name that is reserved to the compiler. You are not allowed to define one named __cleanup__. This guarantees that your code using __cleanup__ is unaffected by other code (provided that other code behaves, of course).
As https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax explains:
You may optionally specify attribute names with __ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn.
(But note that attributes are not preprocessor directives.)
I've seen Scala using both interchangeably, but I don't know when to use one or the other.
Is there a convention?
For instance these are equivalent
"hello" toString
and
"hello".toString()
And they can even be mixed
"hello".toString() length
What's the convention?
The space convention is generally used when the method functions like an operator (+, *, etc.); the dot convention is used when it functions more like, well, a method call.
(I know that explanation is kind of vague, but there's not really a hard and fast rule for the usage.)
To expand on the comment from Yardena, there is an Scala unofficial style guide. It has some suggestions on when to use the dot notation and when to drop the dot and the parenthesis and usually provides a brief rationale for the recommendation, that you may or may not agree with, but at least that's a starting point.
For instance name toList may behave differently depending on what's on the next line.
Personally, I would write hello.toString.length with the assumption that all calls are side-effect free (so I drop the parenthesis) and then I have to keep the dot for it to compile.