Show syntax errors in knitr output? - knitr

I'm writing a description of R syntax, and I'd like to include some statements that include syntax errors, e.g.
if (n >= 2)
{
# if TRUE
}
else
{
# if FALSE
}
(This is a syntax error at top level because the if is complete before the else is read.) I'm trying to put this into a knitr document, but
even with error=TRUE it fails, because that option only affects run-time errors, not syntax errors. Is there some reasonable way to get this to display what would be shown if I entered it at the console? I.e.
I'd like it to display something like
if (n >= 2)
{
# if TRUE
}
else
Error: unexpected 'else' in "else"
{
# if FALSE
}

Here's a function that does part of what I want: it reproduces the output from a syntax error, but it doesn't do all the markup that knitr would do, so the formatting is wrong.
parse_with_error <- function(text) {
reportError <- function(e) {
msg <- conditionMessage(e)
line <- as.numeric(sub("^text:([[:digit:]]*):.*", "\\1", msg))
col <- as.numeric(sub("^text:[[:digit:]]*:([[:digit:]]*):.*", "\\1", msg))
cat(text[1:line], sep="\n")
if (col > 1)
cat(paste(rep(" ", col-1), collapse=""))
cat("^\n")
err <- sub("^text:[[:digit:]]*:[[:digit:]]*: ([^[:cntrl:]]*)\n.*", "\\1", msg)
parseData <- getParseData(sf)
lastToken <- parseData[nrow(parseData), "text"]
cat(paste0("Error: ", err, ' in "', lastToken, '"'), "\n")
}
text <- unlist(strsplit(text, "\n"))
sf <- srcfile("text")
tryCatch(parse(text = text, keep.source = TRUE, srcfile=sf),
error = reportError)
}
This shows how it would be used:
parse_with_error(
"if (TRUE) {
# do TRUE
}
else {
# do FALSE
}")

You can use a separate R session to evaluate the code, e.g.
```{r, engine='Rscript', error=TRUE}
if (TRUE)
{
# if TRUE
}
else
{
# if FALSE
}
```

Related

Swift if directive quirk

Suppose I have a complex chain of ifs. Now I want to be sure that one of the conditions are triggered, so I add the final line to notify me when nothing was triggered.
if condition1 ...
else if condition2 ...
else if condition3 ...
else print( "Ooops nothing triggered" )
Since I only want to print this in DEBUG mode, I wrap the final line
#if DEBUG
else print( "Ooops nothing triggered" )
#endif
and I get the strangest errors. "Closure expression is unused" and "Expected expression".
Here is some simple working code to illustrate with.
let x = Int ( arc4random_uniform ( 100 ) ) - 50
// This works
if x > 0 { print ( "Positive" ) }
else if x < 0 { print ( "Negative" ) }
else { print ( "Oops - neither" ) }
// After adding the #if this does not compile
if x > 0 { print ( "Positive" ) }
else if x < 0 { print ( "Negative" ) }
#if DEBUG
else { print ( "Oops - neither" ) }
#endif
Obviously Swift's conditional compilation here fails. I wonder why and ask how to to do this so that the test is only applied in DEBUG mode?
FWIW I am not interested in e.g. using switch - the actual logic is complex. How to do this with ifs and else ifs if possible please?
These #ifs don't really work like those preprocessor directives in C. They
According to the grammar, the syntax of these directives are the following:
if-directive-clause → if-directive compilation-condition statements(opt)
elseif-directive-clauses → elseif-directive-clause elseif-directive-clauses(opt)
elseif-directive-clause → elseif-directive compilation-condition statements(opt)
else-directive-clause → else-directive statements(opt)
if-directive → #if
elseif-directive → #elseif
else-directive → #else
endif-directive → #endif
Note that an if-directive-clause consists of #if, then a compilation-condition, then some statements. Not just anything, but statements.
else { print ( "Oops - neither" ) }
is not a statement (or a list of statements).
How about putting the #if inside the else block? That is guaranteed to be a statements:
if x > 0 { print ( "Positive" ) }
else if x < 0 { print ( "Negative" ) }
else {
#if DEBUG
print ( "Oops - neither" )
#endif
}

How to delete pattern which matches with the next new pattern which is calling in the next line by using /bin/sed command in dc_shell

Below is the example of my file,
signal {
{
ab
cd
}
"m_1_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"m_0_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
"m_0_clk" {
Data S Mk {
Active Up;
}
}
"m_1_clk" {
Data S Mk {
Active Up;
}
}
}
I am expecting the output from above file to be:
signal {
{
ab
cd
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
}
Hi,
Above is the example of my file
I would like to delete pattern which matches the next pattern which is calling in the next line.
Trying to search the specific pattern for deleting the lines which it should not be present in my file.
Need to search the specific pattern with new pattern in the next line. because first line is calling in multiple loops. so should grep specific pattern of all the content.
I tried using the below command in tcl its not working. could anyone help me on this,
below is the sed command used in tcl
exec /bin/sed -e {s/\m\(.*\)clk" {\.*\n\.*Data\.*//} -i file
exec /bin/sed -e {s/\m\(.*\)clk" {\.*\n\.*P {\.*//} -i file
Could you please try following and let me know if this helps you.(Considering that your actual Input_file is same as shown sample file)
awk -v line_number=$(cat Input_file | wc -l) '/signal {/ || /"o_\[9\]" {/ || FNR==line_number{flag=1}; /^$/{flag=""} flag' Input_file
Explanation: Adding explanation for code too now as follows:
awk -v line_number=$(cat Input_file | wc -l) ' ##Creating variable named line_number in awk script whose value is number of lines of Input_file.
/signal {/ || /"o_\[9\]" {/ || FNR==line_number{ ##checking condition here if a line contains strings either signal { OR "o_\[9\]" { then do following:
flag=1} ##Setting variable named flag here and setting its value to 1 here.
/^$/{ ##Checking condition here if a line is NULL or BLANK then do following:
flag=""} ##Nullifying the variable flag here.
flag ##awk works on method of condition then actions, so checking if variable flag value is NOT NULL here and not mentioning any action here so by default peint of current line will happen here.
' Input_file ##Metioning the Input_file name here.
Solution with a context-sensitive parser:
use Marpa::R2 qw();
my $input = <<'INPUT';
signal {
{
ab
cd
}
"m_1_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"m_0_clk" {
P {
'0ns' D;
'25ns' U;
'65ns' D;
}
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
"m_0_clk" {
Data S Mk {
Active Up;
}
}
"m_1_clk" {
Data S Mk {
Active Up;
}
}
}
INPUT
my $grammar = Marpa::R2::Scanless::G->new({
bless_package => 'Foo',
source => \<<'GRAMMAR',
:default ::= action => [values] bless => ::lhs
lexeme default = action => [ value ] bless => ::name latm => 1
:start ::= blocks
blocks ::= block+
block ::= optionalname [{] contentblocks [}] optionalws
optionalname ::= name | epsilon
contentblocks ::= contentorblock+
contentorblock ::= content | block
name ~ [a-zA-Z0-9_"\x{5b}\x{5d} ]+
content ~ [a-zA-Z0-9;'\s]*
optionalws ~ [\s]*
epsilon ::=
GRAMMAR
});
my $parser = Marpa::R2::Scanless::R->new({grammar => $grammar});
$parser->read(\$input);
my $output;
deleteblocks($parser->value->$*);
print $output;
sub deleteblocks {
my ($v) = #_;
return if ref $v eq 'Foo::block' and $v->[0][0]
and $v->[0][0][0] !~ /signal|"o_\[9\]"/;
if (ref $v) {
deleteblocks($_) for $v->#*;
} else {
$output .= $v || '';
}
}
Output is:
signal {
{
ab
cd
}
"o_[9]" {
Data S Mk {
Active Up;
}
}
}

How to implement the Lispian cond macro?

Intended usage:
cond! {
x > 5 => 0,
x < 3 => 1,
true => -1
}
Should expand to:
if x > 5 { 0 } else if x < 3 { 1 } else if true { -1 }
Note that it doesn't produce a catch-all else { ... } suffix.
My attempt:
macro_rules! cond(
($pred:expr => $body:expr) => {{
if $pred {$body}
}};
($pred:expr => $body:expr, $($preds:expr => $bodies:expr),+) => {{
cond! { $pred => $body } else cond! { $($preds => $bodies),+ }
}};
);
However, the compiler complains about the else keyword.
error: expected expression, found keyword `else`
--> src/main.rs:32:34
|
32 | cond! { $pred => $body } else cond! { $($preds => $bodies),+ }
| ^^^^
Macros in Rust don't perform textual substitution like the C preprocessor does. Moreover, the result of a macro is already "parsed", so you can't just append something after the macro invocation that's supposed to be part of what the macro expands to.
In your case, you can't put an else after the first cond! invocation because the compiler has already finished parsing the if expression; you need to put the if and the else together. Likewise, when you invoke cond! again after the else, you need to add braces around the call, because the sequence else if does not begin a nested if expression.
macro_rules! cond {
($pred:expr => $body:expr) => {
if $pred { $body }
};
($pred:expr => $body:expr, $($preds:expr => $bodies:expr),+) => {
if $pred { $body } else { cond! { $($preds => $bodies),+ } }
};
}
Ultimately though, this macro is pretty much useless. An if expression without an else clause always has its type inferred to be (), so unless all the branches evaluate to () (or diverge), the expanded macro will produce type mismatch errors.

Syntax error when map() returns LIST

This works,
print map { $_." x" => $_ } 1..5;
print map { ("$_ x" => $_) } 1..5;
print map { ("$_ x") => $_ } 1..5;
but this throws syntax error,
print map { "$_ x" => $_ } 1..5;
Is this documented bug, undocumented bug, or I can't see why this should not compile?
Why perl thinks this should be map EXPR, LIST instead of map BLOCK LIST
From perlref
Because curly brackets (braces) are used for several other things including BLOCKs, you may occasionally have to disambiguate braces at the beginning of a statement by putting a + or a return in front so that Perl realizes the opening brace isn't starting a BLOCK. The economy and mnemonic value of using curlies is deemed worth this occasional extra hassle.
To make your intentions clearer and to help the parser,
Say +{...} to unambiguously specify a hash reference
#list_of_hashrefs = map +{ "$_ x" => $_ }, 1..5;
Say {; ...} to unambiguously specify a code block
%mappings = map {; "$_ x" => $_ } 1..5;
Why perl thinks this should be map EXPR, LIST instead of map BLOCK LIST?
The relevant section of code is in toke.c, Perl's lexer (the below is from Perl 5.22.0):
/* This hack serves to disambiguate a pair of curlies
* as being a block or an anon hash. Normally, expectation
* determines that, but in cases where we're not in a
* position to expect anything in particular (like inside
* eval"") we have to resolve the ambiguity. This code
* covers the case where the first term in the curlies is a
* quoted string. Most other cases need to be explicitly
* disambiguated by prepending a "+" before the opening
* curly in order to force resolution as an anon hash.
*
* XXX should probably propagate the outer expectation
* into eval"" to rely less on this hack, but that could
* potentially break current behavior of eval"".
* GSAR 97-07-21
*/
t = s;
if (*s == '\'' || *s == '"' || *s == '`') {
/* common case: get past first string, handling escapes */
for (t++; t < PL_bufend && *t != *s;)
if (*t++ == '\\')
t++;
t++;
}
else if (*s == 'q') {
if (++t < PL_bufend
&& (!isWORDCHAR(*t)
|| ((*t == 'q' || *t == 'x') && ++t < PL_bufend
&& !isWORDCHAR(*t))))
{
/* skip q//-like construct */
const char *tmps;
char open, close, term;
I32 brackets = 1;
while (t < PL_bufend && isSPACE(*t))
t++;
/* check for q => */
if (t+1 < PL_bufend && t[0] == '=' && t[1] == '>') {
OPERATOR(HASHBRACK);
}
term = *t;
open = term;
if (term && (tmps = strchr("([{< )]}> )]}>",term)))
term = tmps[5];
close = term;
if (open == close)
for (t++; t < PL_bufend; t++) {
if (*t == '\\' && t+1 < PL_bufend && open != '\\')
t++;
else if (*t == open)
break;
}
else {
for (t++; t < PL_bufend; t++) {
if (*t == '\\' && t+1 < PL_bufend)
t++;
else if (*t == close && --brackets <= 0)
break;
else if (*t == open)
brackets++;
}
}
t++;
}
else
/* skip plain q word */
while (t < PL_bufend && isWORDCHAR_lazy_if(t,UTF))
t += UTF8SKIP(t);
}
else if (isWORDCHAR_lazy_if(t,UTF)) {
t += UTF8SKIP(t);
while (t < PL_bufend && isWORDCHAR_lazy_if(t,UTF))
t += UTF8SKIP(t);
}
while (t < PL_bufend && isSPACE(*t))
t++;
/* if comma follows first term, call it an anon hash */
/* XXX it could be a comma expression with loop modifiers */
if (t < PL_bufend && ((*t == ',' && (*s == 'q' || !isLOWER(*s)))
|| (*t == '=' && t[1] == '>')))
OPERATOR(HASHBRACK);
if (PL_expect == XREF)
{
block_expectation:
/* If there is an opening brace or 'sub:', treat it
as a term to make ${{...}}{k} and &{sub:attr...}
dwim. Otherwise, treat it as a statement, so
map {no strict; ...} works.
*/
s = skipspace(s);
if (*s == '{') {
PL_expect = XTERM;
break;
}
if (strnEQ(s, "sub", 3)) {
d = s + 3;
d = skipspace(d);
if (*d == ':') {
PL_expect = XTERM;
break;
}
}
PL_expect = XSTATE;
}
else {
PL_lex_brackstack[PL_lex_brackets-1] = XSTATE;
PL_expect = XSTATE;
}
Explanation
If the first term after the opening curly is a string (delimited by ', ", or `) or a bareword beginning with a capital letter, and the following term is , or =>, the curly is treated as the beginning of an anonymous hash (that's what OPERATOR(HASHBRACK); means).
The other cases are a little harder for me to understand. I ran the following program through gdb:
{ (x => 1) }
and ended up in the final else block:
else {
PL_lex_brackstack[PL_lex_brackets-1] = XSTATE;
PL_expect = XSTATE;
}
Suffice it to say, the execution path is clearly different; it ends up being parsed as a block.

Scala: for loop until condition

How can I run for until a condition is met? Instead of using scala.util.control.Breaks.break, is it possible to test for a condition within for?
for(line <- source.getLines) {
if (line.equals("")) scala.util.control.Breaks.break
Console print "Message> "
dataWriter.write(line, InstanceHandle_t.HANDLE_NIL)
}
} catch {
case e: IOException =>{
Try takeWhile
for(line <- source.getLines.takeWhile(!_.isEmpty)) {
Console print "Message> "
dataWriter.write(line, InstanceHandle_t.HANDLE_NIL)
}
or
source.getLines.takeWhile(!_.isEmpty).foreach {
line =>
Console print "Message> "
dataWriter.write(line, InstanceHandle_t.HANDLE_NIL)
}