How do I read all of standard input in Idris2? - idris

I'm trying to figure out how to do something very simple: read all of standard input into a string (or a list of strings would be fine too).
Prelude has getLine : HasIO io => io String, which can give me one line, but it doesn't give me a way to know that I've read it all. If there is no more input, it just gives me an empty string, which means if the input contains empty lines, I can't tell that apart from the end of the input.
Consider the following program:
module Example
main : IO ()
module Solve
main : IO ()
main = do
putStrLn ("'" ++ !getLine ++ "'")
putStrLn ("'" ++ !getLine ++ "'")
putStrLn ("'" ++ !getLine ++ "'")
putStrLn ("'" ++ !getLine ++ "'")
putStrLn ("'" ++ !getLine ++ "'")
putStrLn ("'" ++ !getLine ++ "'")
This program will print six lines, each wrapped in single quotes, taking contents from standard input. If I compile it to ./example and run with three lines of input, and a blank line in the middle, here's the output:
$ ./example <<EOF
foo
bar
EOF
'foo'
''
'bar'
''
''
''
Note that it keeps printing out lines after the standard input stream is exhausted. This means if I put this in some recursive function to get me all of the input, I don't have a reasonable stop condition.
What is the idiomatic way to read all of standard input in Idris2, without knowing at build-time how many lines of input there will be?

You can use fEOF.
You can see an example here.

Related

Dataweave2.0 in mule 4

notes=(payload.examples if payload.examples != null else “ “) ++ (\n\n**column1:\ntest: “ ++ vars.name) ++ ( “\n column2: “ ++ vars.date) ++ (“\n column3: “ ++ attributes.headers.speech)
This is DataWeave 2.0 but error said invalid input. Anyone knows how to fix this in mule 4?
As per your comment code of DataWeave 1.0. Please find the below corresponding DataWeave 2.o code.
%dw 2.0
output application/json
---
{
(payload mapObject (value, key) -> {
((key): value) if (key as String != "notes")
}),
notes:
if (payload.examples != null)
payload.examples
else
"" ++ ("\n\n**column1:\ntest: " ++ vars.name) ++ ("\n column2: " ++ vars.date) ++ ("\n column3: " ++ attributes.headers.speech)
}
the part where you are performing the condition check with if, the '=!' should be '!='.Please let me know if this has helped you.

Grammar for string interpolation where malformed interpolations are treated as normal strings

Here is a subset of the language I want to parse:
A program consists of statements
A statement is an assignment: A = "b"
Assignment's left side is an identifier (all caps)
Assignment's right side is a string enclosed by quotation marks
A string supports string interpolation by inserting a bracket-enclosed identifier (A = "b[C]d")
So far this is straight forward enough. Here is what works:
Lexer:
lexer grammar string_testLexer;
STRING_START: '"' -> pushMode(STRING);
WS: [ \t\r\n]+ -> skip ;
ID: [A-Z]+;
EQ: '=';
mode STRING;
VAR_START: '[' -> pushMode(INTERPOLATION);
DOUBLE_QUOTE_INSIDE: '"' -> popMode;
REGULAR_STRING_INSIDE: ~('"'|'[')+;
mode INTERPOLATION;
ID_INSIDE: [A-Z]+;
CLOSE_BRACKET_INSIDE: ']' -> popMode;
Parser:
parser grammar string_testParser;
options { tokenVocab=string_testLexer; }
mainz: stat *;
stat: ID EQ string;
string: STRING_START string_part* DOUBLE_QUOTE_INSIDE;
string_part: interpolated_var | REGULAR_STRING_INSIDE;
interpolated_var: VAR_START ID_INSIDE CLOSE_BRACKET_INSIDE;
So far so good. However there is one more language feature:
if there is no valid identifier (that is all caps) in the brackets, treat as normal string.
Eg:
A = "hello" => "hello"
B = "h[A]a" => "h", A, "a"
C="h [A] a" => "h ", A, " a"
D="h [A][V] a" => "h ", A, V, " a"
E = "h [A] [V] a" => "h ", A, " ", V, " a"
F = "h [aVd] a" => "h [aVd] a"
G = "h [Va][VC] a" => "h [Va]", VC, " a"
H = "h [V][][ff[Z]" => "h ", V, "[][ff", Z
I tried to replace REGULAR_STRING_INSIDE: ~('"'|'[')+; With just REGULAR_STRING_INSIDE: ~('"')+;, but that does not work in ANTLR. It results in matching all the lines above as strings.
Since in ANTLR4 there is no backtracking to enable I'm not sure how to overcome this and tell ANTLR that if it did not match the interpolated_var rule it should go ahead and match REGULAR_STRING_INSIDE instead, it seems to always chose the latter.
I read that lexer always matches the longest token, so I tried to lift REGULAR_STRING_INSIDE and VAR_START as a parser rules, hoping that alternatives order in the parser will be honoured:
r: REGULAR_STRING_INSIDE
v: VAR_START
string: STRING_START string_part* DOUBLE_QUOTE_INSIDE;
string_part: v ID_INSIDE CLOSE_BRACKET_INSIDE | r;
That did not seem to make any difference at all.
I also read that antlr4 semantic predicates could help. But I have troubles coming up with the ones that needs to be applied in this case.
How do I modify this grammar above so that it can match both interpolated bits, or treat them as strings if they are malformed?
Test input:
A = "hello"
B = "h[A]a"
C="h [A] a"
D="h [A][V] a"
E = "h [A] [V] a"
F = "h [aVd] a"
G = "h [Va][VC] a"
H = "h [V][][ff[Z]"
How I compile / test:
antlr4 string_testLexer.g4
antlr4 string_testParser.g4
javac *.java
grun string_test mainz st.txt -tree
I tried to replace REGULAR_STRING_INSIDE: ~('"'|'[')+; With just REGULAR_STRING_INSIDE: ~('"')+;, but that does not work in ANTLR. It results in matching all the lines above as strings.
Correct, ANTLR tries to match as much as possible. So ~('"')+ will be far too greedy.
I also read that antlr4 semantic predicates could help.
Only use predicates as a last resort. It introduces target specific code in your grammar. If it's not needed (which in this case it isn't), then don't use them.
Try something like this:
REGULAR_STRING_INSIDE
: ( ~( '"' | '[' )+
| '[' [A-Z]* ~( ']' | [A-Z] )
| '[]'
)+
;
The rule above would read as:
match any char other than " or [ once or more
OR match a [ followed by zero or more capitals, followed by any char other than ] or a capital (your [Va and [aVd cases)
OR match an empty block, []
And match one of these 3 alternatives above once or more to create a single REGULAR_STRING_INSIDE.
And if a string can end with one or mote [, you may also want to do this:
DOUBLE_QUOTE_INSIDE
: '['* '"' -> popMode
;

Capturing pretty-printed string output, to display multiple variables on a single line in gdb?

In my gdb session, I have typed this:
(gdb) p arg1
$17 = (svn_revnum_t *) 0xbfffea0c
(gdb) p *(arg1)
$18 = -1
Now, I would like the "pretty-printed" output for both commands to be shown in a single line, as in:
$19 = (svn_revnum_t *) 0xbfffea0c ; -1
... so I try something like this:
(gdb) p arg1, ";", *(arg1)
$19 = -1
... but obviously, it doesn't work.
Is there a way to do something like this?
I guess, if it was possible to somehow "capture" the pretty-printed output of print as a string, then I could use printf "%s ; %s" to format my output; but how would one capture the print output, then?
I think the simplest way to do this is to write a new Python command that does what you want.
Alternatively you could write a Python convenience function that uses str on its argument. Then, use that with printf.

Lex : line with one character but spaces

I have sentences like :
" a"
"a "
" a "
I would like to catch all this examples (with lex), but I don't how to say the beginning of the line
I'm not totally sure what exactly you're looking for, but the regex symbol to specify matching the beginning of a line in a lex definition is the caret:
^
If I understand correctly, you're trying to pull the "a" out as the token, but you don't want to grab any of the whitespace? If this is the case, then you just need something like the following:
[\n\t\r ]+ {
// do nothing
}
"a" {
assignYYText( yylval );
return aToken;
}

Is it possible to override rebol path operator?

It is possible to overide rebol system words like print, make etc., so is it possible to do the same with the path operator ? Then what's the syntax ?
Another possible approach is to use REBOL meta-programming capabilities and preprocess your own code to catch path accesses and add your handler code. Here's an example :
apply-my-rule: func [spec [block!] /local value][
print [
"-- path access --" newline
"object:" mold spec/1 newline
"member:" mold spec/2 newline
"value:" mold set/any 'value get in get spec/1 spec/2 newline
"--"
]
:value
]
my-do: func [code [block!] /local rule pos][
parse code rule: [
any [
pos: path! (
pos: either object? get pos/1/1 [
change/part pos reduce ['apply-my-rule to-block pos/1] 1
][
next pos
]
) :pos
| into rule ;-- dive into nested blocks
| skip ;-- skip every other values
]
]
do code
]
;-- example usage --
obj: make object! [
a: 5
]
my-do [
print mold obj/a
]
This will give you :
-- path access --
object: obj
member: a
value: 5
--
5
Another (slower but more flexible) approach could also be to pass your code in string mode to the preprocessor allowing freeing yourself from any REBOL specific syntax rule like in :
my-alternative-do {
print mold obj..a
}
The preprocessor code would then spot all .. places and change the code to properly insert calls to 'apply-my-rule, and would in the end, run the code with :
do load code
There's no real limits on how far you can process and change your whole code at runtime (the so-called "block mode" of the first example being the most efficient way).
You mean replace (say)....
print mold system/options
with (say)....
print mold system..options
....where I've replaced REBOL's forward slash with dot dot syntax?
Short answer: no. Some things are hardwired into the parser.