Different separators for the same variable in Rust Macros - rust

I want to match a pattern like:
foo!(1,2,3;4,5,6;7,8,9);
The same code would be generated for all numbers, but I'd want additional code to run when there's a semi-colon. Is this sort of pattern possible?
I've tried:
macro_rule! {
foo ($($x:expr),*);*) => ...
But I can't seem to make that work on the right-hand side.

You never explained what the problem was with your existing code, so I don't know what to highlight in this example:
macro_rules! foo {
($($($x:expr),*);*) => {
$(
$(
print!("{},", $x);
)*
println!("semi");
)*
}
}
fn main() {
foo!(1,2,3;4,5,6;7,8,9);
}
I can point out things from your original code:
It's called macro_rules!, not macro_rule!
The name of the macro being defined goes before the original {, not after.
Like most programming, paired delimiters need to be evenly matched to be syntactically valid.
The Rust Programming Language, first edition has several pieces of valuable information.
Basic syntax for defining a macro is covered in the macros chapter; I strongly suggest you read the entire thing. It also links to the reference, which contains some more lower-level detail.
The section most related to your question is:
Repetition
The repetition operator follows two principal rules:
$(...)* walks through one "layer" of repetitions, for all of the $names it contains, in lockstep, and
each $name must be under at least as many $(...)*s as it was matched against. If it is under more, it’ll be duplicated, as appropriate.

Related

Finding the start of an expression when the end of the previous one is difficult to express

I've got a file format that looks a little like this:
blockA {
uniqueName42 -> uniqueName aWord1 anotherWord "Some text"
anotherUniqueName -> uniqueName23 aWord2
blockB {
thing -> anotherThing
}
}
Lots more blocks with arbitrary nesting levels.
The lines with the arrow in them define relationships between two things. Each relationship has some optional metadata (multi-word quoted or single word unquoted).
The challenge I'm having is that because the there can be an arbitrary number of metadata items in a relationship my parser is treating anotherUniqueName as a metadata item from the first relationship rather than the start of the second relationship.
You can see this in the image below. The parser is only recognising one relationshipDeclaration when a second should start with StringLiteral: anotherUniqueName
The parser looks a bit like this:
block
: BLOCK LBRACE relationshipDeclaration* RBRACE
;
relationshipDeclaration
: StringLiteral? ARROW StringLiteral StringLiteral*
;
I'm hoping to avoid lexical modes because the fact that these relationships can appear almost anywhere in the file will leave me up to my eyes in NL+ :-(
Would appreciate any ideas on what options I have. Is there a way to look ahead, spot the '->', for example?
Thanks a million.
Your example certainly looks like the NL is what signals the end of a relationshipDeclaration.
If that's the case, then you'll need NLs to be tokens available to your parse rules so the parser can know recognize the end.
As you've alluded to, you could potentially use -> to trigger a different Lexer Mode and generate different tokens for content between the -> and the NL and then use those tokens in your parse rule for relationshipDeclaration.
If it's as simple as your snippet indicates, then just capturing RD_StringLiteral tokens in that lexical mode, would probably be easier to deal with than handling all the places you might need to allow for NL. This would be pretty simple as Lexer modes go.
(BTW you can use x+ to get the same effect as x x*)
relationshipDeclaration
: StringLiteral? ARROW RD_StringLiteral+
;
I don't think there's a third option for dealing with this.

What is the difference between vec![] and vec!()

I found out that I can use both vec![] and vec!() in my code and they both do the same -- initialize a Vec. I found no documentation on the later form though. Is it indeed the same thing? Which one should I use? Why?
Macros can be invoked using [], (), or {}.
Which delimiter is used makes no actual difference to the way it executes, though usually people will use braces for “block-like” or “definition” macros (e.g. tokio’s select), brackets for literal-like (vec) and parens for function-like expressions (e.g. println or matches).
In fact there are 3 forms (), [] and {} and they're all identical.
https://users.rust-lang.org/t/braces-square-brackets-and-parentheses-in-macro-call/9984/2
Yes, they are identical. Use whichever you like best. Usually () is for function-like macros, [] is used for vec![…], and {} is for other cases.

Are there parts of the Rust language that only work on multiple lines?

Is it possible to take any Rust code and make it work in only one line (without any line breaks)? In particular, it should work exactly like the "normal" multi line code:
if it's an executable, the runtime behavior should be the same.
if it's a library, the documentation and .rlib file should be the same.
This is a purely theoretical question and I don't plan on actually writing my Rust code like this :P
I know that most typical Rust code can be written in one line. Hello world is easy-peasy:
fn main() { println!("Hello, world"); }
Are there any Rust constructs that can't be written in one line? I thought of a few candidates already:
Doc comments. I usually see them written as /// or //! and they include everything until the end of the line.
Macros, especially procedural ones, can do some strange unexpected things. Maybe it is possible to construct macros that only work on multiple lines?
String literals can be written over multiple lines in which case they will include the linebreaks. I know that those line breaks can also be written as \n, but maybe there is something about multi-line strings that does not work in a single line? Maybe something something about raw string literals?
Maybe some planned future extensions of Rust?
Probably many other things I didn't think of...
Out of curiosity, I did a quick read through of Rust's Lexer Code and there is only one case (that I noticed) which requires a newline and can not be rewritten any other way. As people have pointed out, there are directly equivalent ways to write doc comments, string literals, and macros which can be done on a single line.
That being said, this is technically not considered Rust syntax. However, it has been part of rustc since the creation of rustc_lexer (4 years ago) and likely long before that so I'm going to count it. Plus if we squint really hard then it kind of looks like it might just fit the restriction of "if it's an executable, the runtime behavior should be the same".
Rust files allow the inclusion of a shebang on the first line. Since shebang's are a Unix convention, Rust needs to follow the existing standard (which requires a line break before the rest of the file contents). For example, it is not possible to write this Rust file without any newline characters in a way that preserves the behavior when run (cough on systems that support shebangs cough):
#!/usr/bin/rustrun
fn main() {
println!("Hello World!");
}
Rust Playground (You won't be able to try using the shebang on Rust Playground, but at least you can see it compiles and can not be reduced to a single line)
For anyone who is curious, here is how it is described in the lexer code:
/// `rustc` allows files to have a shebang, e.g. "#!/usr/bin/rustrun",
/// but shebang isn't a part of rust syntax.
pub fn strip_shebang(input: &str) -> Option<usize> {
// Shebang must start with `#!` literally, without any preceding whitespace.
// For simplicity we consider any line starting with `#!` a shebang,
// regardless of restrictions put on shebangs by specific platforms.
if let Some(input_tail) = input.strip_prefix("#!") {
// Ok, this is a shebang but if the next non-whitespace token is `[`,
// then it may be valid Rust code, so consider it Rust code.
let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok| {
!matches!(
tok,
TokenKind::Whitespace
| TokenKind::LineComment { doc_style: None }
| TokenKind::BlockComment { doc_style: None, .. }
)
});
if next_non_whitespace_token != Some(TokenKind::OpenBracket) {
// No other choice than to consider this a shebang.
return Some(2 + input_tail.lines().next().unwrap_or_default().len());
}
}
None
}
https://github.com/rust-lang/rust/blob/e1c91213ff80af5b87a197b784b40bcbc8cf3add/compiler/rustc_lexer/src/lib.rs#L221-L244

What is the usage of Nested comments in some programming languages?

Why nested comments use by some programming languages such as MATLAB ,I just want to know usage of this kind comments in a program and what are the advantages we can gain by using this nested comments ?
The answer is nested comments allows commented-out code that contains comments itself
example in C++ has block comments delimited by /../ that can span multiple lines and line comments delimited by //.
Usually, coding standards for a particular project or program have rules about which comment style to use when; a common convention is to use block comments (/* */) for method and class documentation, and inline comments (//) for remarks inside method bodies and such, e.g.:
/**
* Helper class to store Foo objects inside a bar.
*/
public class Foobar {
/**
* Stores a Foo in this Foobar's bar, unless the bar already contains
* an equivalent Foo.
* Returns the number of Foos added (always 0 or 1).
*/
public int storeFoo(Foo foo) {
// Don't add a foo we already have!
if (this.bar.contains(foo)) {
return 0;
}
// OK, we don't have this foo yet, so we'll add it.
this.bar.append(foo);
return 1;
}
}
If someone wants to temporarily disable entire methods or classes in the above program.It's very helpful, if that language allows nested comments.
You can use comments...:
to temporally disable some lines of code.
as titles for sections.
to comment each line.
to add some notations or comments on other comments.
to send macro orders.
And you can mix all of them. That's why we need different ways to mark comments and create nested comments.
Good old Turbo Pascal aka Borland Pascal allows multi-line comments either with curly braces { } or with parenthesis star (* *), which nest independently of one another even though multi-line comments in the same style do not nest.
A good workaround from my old work place was use of typical brace { } comments for all informational comments and specialized use of the less common parenthesis star (* *) only to comment out code. Marking the middle lines of commented out code with something like ** is still a decent idea, and macros can be used to achieve this in programmer editors
function ComputeCost(var x : longint);
{ Wide version: Apply discounts to raw price.}
(* CODE GRAVEYARD!
** function ComputeCost(var x : integer);
** {Apply discounts to raw price.}
*)
Minimalists will always discount the need for nested comments by saying that C style languages allow constructs like #ifdef SOMETHING or the elegantly short #if 0 to disable code. True minimalists want old code removed completely and say version control takes the place of keeping old code. A good counter is that commented out code together with programmer editors with folding support, e.g. Vim, allows visually stepping over dead code while keeping it for reference.
I feel that nested comments are not necessary! In general a comment is omitted by the compiler so comments serve a main purpose for indicating the programmer what he had done or a new programmer to know the flow of the program..why unnecessarily nest comments..just an indication that can be without nesting.. eg:
for(;;)
{
if()
{
}
}/* a loop with an if condition*/
**need not be as**
/*a loop/*if condition*/for n times*/

groovy: use brackets on method calls or not?

this is a fairly general question about whether people should be using brackets on method calls that take parameters or not.
i.e.
def someFunc(def p) {
...
}
then calling:
someFunc "abc"
vs...
someFunc("abc")
Is this just a question of consistency, or is there specific use cases for each?
It's primarily a question of consistency and readability, but note that Groovy won't always let you get away with omitting parentheses. For one, you can't omit parentheses in nested method calls:
def foo(n) { n }
println foo 1 // won't work
See the section entitled "Omitting parentheses" in the Style guide.
There's no specific case where you must remove them, you can always use them. It's just prettier to leave them out.
There are cases where you can't do that (where you could confuse a list/map parameter with a subscript operator for instance, nested calls, or when the statement is an assignment), but the general rule is that the outmost call can have no parenthesis if there is no ambiguity.
(deleted several lines, as I've just received notification that there is a post already with that info)
Groovy 1.8 will allow even more cases to omit parenthesis, you can check them out at
http://groovyconsole.appspot.com/script/355001
"an empty pair of parentheses is just useless syntactical noise!"
It seems to me that they are encouraging you to use parenthesis when they serve a purpose, but omit them when they are just "noise"

Resources