List<Set<String>> iDontGetIt() {
var test = [
for (final e in [2, 4, 6])
if (e == 4) {
'What?!'
}
];
return test;
}
If I run this code I return 'test' which is equal to [{What?!}]. I can insinuate that there is an inferred return statement after (y == 4) that is returning {'What?!'}.
However, in my head I would expect to write that code with the curly braces representing the control structure of the code, not an indication that a set should be created:
List<String> iDontGetIt() {
var test = [
for (final e in [2, 4, 6]) {
if (e == 4) {
return 'What?!';
}}
];
return test;
}
I would read this to myself as "The test variable is going to equal a list. Inside that list a for loop is going to run looking at each element of the 2,4,6 list. A code block represented by the curly braces will run on each iteration of the loop. The block says that if the element is equal to 4 then we will once again enter a code block inside the curly braces. This second block will return the string 'What?!', placing it in the list. If it the code block above doesn't equal 4, we'll move to the end of the block and then into the next iteration of the loop."
Using that logic, if I ran the code I would return test which would be equal to a List<String> ['What?!'].
I'm obviously wrong, because the linter tells me there is Unexpected text 'return', but this goes against how I expect the control structure of code to function. Every time I've come across a for or if statement there are curly braces that explicitly state what code block should run. I even see this on https://dart.dev/guides/language/language-tour#control-flow-statements where they illustrate with curly braces representing code blocks, not the creation of a set.
Can someone help me understand why there is a deviation from the curly braces representing a code block, show me where this is explained on dart.dev, or otherwise just help me understand what's going on?
The difference is that the if and for inside a collection literal contains an expression, not a statement.
The {statements} block statement can contain zero or more statements.
Can't use that inside an expression.
As an expression, {"What"} is a set literal. You also cannot use return as an expression.
It's basically the same as the difference between the statements
{ return "What"; }
and
return {"What"};
Also to better understand the context, this was the proposal on how to include this sintax sugar, I'm linking the line where some light can be found about the confusions:
control-flow-collections draft
Related
Without giving too much details, this sample snippet demonstrates the problem:
-- Add an extra predefined argument
function one_more_arg(...)
local args = {...}
return function()
print(table.unpack(args), "c")
end
end
local my_new_print = one_more_arg("a", "b")
my_new_print() -- "a c"
Apparently unpacking a table does not work in this scenario. Any ideas on how to make this work, ie print will receive "a", "b", "c"? I'm trying to avoid modifying args, unless it's the only way to achieve it.
When you place table.unpack() as an argument to function there should be no other arguments or it should be the last one. Otherwise only first value from table will be passed.
Lua always adjusts the number of results from a function to the
circumstances of the call. When we call a function as a statement, Lua
discards all of its results. When we use a call as an expression, Lua
keeps only the first result. We get all results only when the call is
the last (or the only) expression in a list of expressions. These
lists appear in four constructions in Lua: multiple assignment,
arguments to function calls, table constructors, and return
statements.
From http://www.lua.org/pil/5.1.html
So you can try to put unpack at the end if it is ok for you:
print("c", table.unpack(args))
Or modify args.
table.concat (list [, sep [, i [, j]]])
Given a list where all elements are strings or numbers, returns the string list[i]..sep..list[i+1] ยทยทยท sep..list[j]. The default value for sep is the empty string, the default for i is 1, and the default for j is #list. If i is greater than j, returns the empty string.
Is there an efficient algorithm for finding broken parenthesis in a block of text for the purpose of intellisense error highlighting?
For instance:
function f() {
var a = [1, 2, 3];
if ((a[1] < 1) || (a[0] > 2)) {
console.log((a + 5).toString());
}
}
Where any (, ), [, ], {, or } character might be dropped or adding in correctly and the correct issue might be highlighted, for instance spotting the specific statement, function, conditional, etc level item causing the issue?
The algorithm is not difficult:
Have a stack of characters
For each character in the code:
If it's an opening bracket, push it onto the stack
If it's a closing bracket, pop one char from the stack, both must match
At the end the stack must be empty
Then you could maybe highlight the unmatched bracket(s).
I think that one way of approaching your problem is to validate the matching bracket groups. This may be achieved using the regular expression - see: http://blog.stevenlevithan.com/archives/javascript-match-nested of Steven Levithan.
Can anyone provide a clear explanation and some simple examples that show this error, apparently related to match-time capture (Cmt) ?
I don't understand the only mention that I can find, which is at
http://lua-users.org/lists/lua-l/2013-06/msg00086.html
Thanks
So this question is a bit old, but it's one of the first search results. There's not a lot on the Internet about this, and it may not be super obvious what's wrong.
The error message is a bit misleading, but what's happening - in formal PEG terms, at least as I understand them - there is a repetition operator applied to an parsing expression that can consume no input.
Or other words, LPeg has detected a loop that can match an empty string, which will never complete. There's a pure Lua implementation called LuLPeg which lacks this particular check, and if you execute your grammar it could easily enter an infinite loop.
I'm tinkering with little toy BASIC-ish language, and had the above issue with the following:
grammar = P{ "input",
input = V"block"^0 * -1,
block = V"expression"^0,
-- (define expression here)
}
With that idea that the root input is an optional block of code, and a block is zero or more expressions. This is pretty simplified, of course, I'm leaving out whitespace handling and that sort of thing. But what happens when you call grammar:match("")?
remaining string: "", at input. See if it matches a block.
remaining string: "", at block. See if it matches an expression.
remaining string: "", at expression. For the sake of time, let's say it doesn't match
remaining string: "", at block. Rule concludes with zero expressions, no input consumed.
remaining string: "", at input. One block consumed, check if more blocks match.
remaining string: "", at block. See if it matches an expression.
And so on. Since V"block" matches the empty string, input can find an infinite number of blocks to fulfil the rule V"block"^0. In this case, there's two good solutions: Set input to at most one block, or require block to be a least one expression and wherever there could be a block set it to ^0. So either:
grammar = P{ "input", -- blocks can be empty, input contains one (empty or otherwise) block
input = V"block" * -1,
block = V"expression"^0,
-- (define expression here)
}
Or:
grammar = P{ "input", -- blocks must be at least one expression, root can have one
input = V"block"^0 * -1,
block = V"expression"^1,
-- (define expression here)
}
In the first case, an empty string will match a block, which fulfills the the input rule. In the second, an empty string will fail block, fulfilling the input rule with zero matching blocks.
I haven't needed to use Cmt yet, but I believe what happened was old versions of LPeg assumed the function would either fail or consume input, even if the rule inside the Cmt call could match an empty string. More recent releases don't have this assumption.
I have the following code which enables me to make console output appear on the same line. However, if a value that was previously printed was of greater length than values after it, the remnants of the longer value will show up. I have seen other questions about the same thing in languages like Python, but I'm not sure how to overcome this in Rust.
Here's an example:
use std::io::prelude::*;
fn main() {
let fruits = ["Blueberry", "Orange", "Cherry", "Lemon", "Apple"];
print_value(&fruits);
}
fn print_value(e: &[&str]) {
for val in e {
print!("\rStatus: {}", val);
std::io::stdout().flush().unwrap();
// pause program temporarily
std::thread::sleep(std::time::Duration::new(2, 0));
}
}
Some terminals have a special character sequence that, when printed, clears the line to the right of the current cursor position.
VT100-compatible terminals have a character sequence EL0 for that. In Rust it can be expressed with "\x1B[K".
Here's a little thingy that might prove an example.
To do that in a more portable way you use a terminal library, such as term and it's delete_line method.
I am writing a JavaCC parser/lexer which is meant to recognise all input strings in the following language L:
A string from L consists of several blocks separated by space characters.
At least one block must be present (i.e., no input consisting only of some number of white spaces is allowed).
A block is an odd-length sequence of lowercase letters (a-z).
No spaces are allowed before the first block or after the last one.
The number of spaces between blocks must be odd.
The I/O specifications include the following specification:
If the input does represent a string from L, then the word YES must be printed out to System.out, ending with the EOL character.
If the input is not in L, then only a single line with the word NO needs
to be printed out to System.out, also ending with the EOL character.
In addition, a brief error message should be printed out on System.err explaining the reason why the input is not in L.
Issue:
This is my current code:
PARSER_BEGIN(Assignment)
/** A parser which determines if user's input belongs to the langauge L. */
public class Assignment {
public static void main(String[] args) {
try {
Assignment parser = new Assignment(System.in);
parser.Input();
if(parser.Input()) {
System.out.println("YES"); // If the user's input belongs to L, print YES.
} else if(!(parser.Input())) {
System.out.println("NO");
System.out.println("Empty input");
}
} catch (ParseException e) {
System.out.println("NO"); // If the user's input does not belong to L, print NO.
}
}
}
PARSER_END(Assignment)
//** A token which matches any lowercase letter from the English alphabet. */
TOKEN :
{
< ID: (["a"-"z"]) >
}
//* A token which matches a single white space. */
TOKEN :
{
<WHITESPACE: " ">
}
/** This production is the basis for the construction of strings which belong to language L. */
boolean Input() :
{}
{
<ID>(<ID><ID>)* ((<WHITESPACE>(<WHITESPACE><WHITESPACE>)*)<ID>(<ID><ID>)*)* ("\n"|"\r") <EOF>
{
System.out.println("ABOUT TO RETURN TRUE");
return true;
}
|
{
System.out.println("ABOUT TO RETURN FALSE");
return false;
}
}
The issue that I am having is as follows:
I am trying to write code which will ensure that:
If the user's input is empty, then the text NO Empty input will be printed out.
If there is a parsing error because the input does not follow the description of L above, then only the text NO will be printed out.
At the moment, when I input the string "jjj jjj jjj", which, by definition, is in L (and I follow this with a carriage return and an EOF [CTRL + D]), the text NO Empty input is printed out.
I did not expect this to happen.
In an attempt to resolve the issue I wrote the ...TRUE and ...FALSE print statements in my production (see code above).
Interestingly enough, I found that when I inputted the same string of js, the terminal printed out the ...TRUE statement once, immediately followed by two occurrences of the ...FALSE statement.
Then the text NO Empty input was printed out, as before.
I have also used Google to try to find out if I am incorrectly using the OR symbol | in my production Input(), or if I am not using the return keyword properly, either. However, this has not helped.
Could I please have hint(s) for resolving this issue?
You're calling the Input method three times. The first time it will read from stdin until it reaches the end of the stream. This will successfully parse the input and return true. The other two times, the stream will be empty, so it will fail and return false.
You shouldn't call a rule multiple times unless you actually want it to be applied multiple times (which only makes sense if the rule only consumes part of the input rather than going until the end of the stream). Instead when you need the result in multiple places, just call the method once and store the result in a variable.
Or in your case you could just call it once in the if and no variable would even be needed:
Assignment parser = new Assignment(System.in);
if(parser.Input()) {
System.out.println("YES"); // If the user's input belongs to L, print YES.
} else {
System.out.println("NO");
System.out.println("Empty input");
}
When the input is jjj jjj jjj followed by a newline or carriage return (but not both), your main method invokes Parser.Input three times.
The first time, your parser consumes all the input and returns true.
The second and third times, all the input having already been consumed, the parser returns false.
Once the input is consumed, the lexer will just keep returning <EOF> tokens.