I unefficiently use "^a + ESC SPACE -- SPACE" and "^a + ]".
1. How can I copy a big file to GNU Screen buffer like
^a + : cat big_file > new_buffer
^a + : new_buffer ]
2. How can specify the number for each buffer like
^a + : cat big_file 2> new_buffer_number_2
^a + 2]
Maybe you want :readbuf?
^A :readbuf /path/to/file
^A ]
I haven't used 'buffers' in GNU Screen (never knew they existed), but I'm guessing :readreg is the buffer-y version of :readbuf:
^A :readreg x /path/to/file
^A :paste x
Related
I made a simple grammar for parsing regular expressions. Unfortunately, when I try to test my regex compiler on large expressions I reach StackOverflowException. The problem is similar to this one except that their solution no longer works in my scenario. Here is my grammar:
union: concat | concat '|' union ;
concat: kleene_closure concat | kleene_closure;
kleene_closure: atomic '*' | atomic ;
atomic : '(' union ')' | LETTER ;
Now the problem is that I have a really large file that looks like
something1 | something2 | something3 | .... | something1000
I use ANTLR's Visitor class for parsing. I know I could probably make some optimization by using +/* like this
union: (concat '|')* concat ;
concat: kleene_closure+;
kleene_closure: atomic '*' | atomic ;
atomic : '(' union ')' | LETTER ;
However, it doesn't really solve the problem, due to recursive nature of this grammar. For instance, it would now fail on the following sample that clearly requires recursion:
(...(((something1) | something2) | something3) | .... ) | something1000
How can I avoid StackOverflowExcpetion? How do other compilers, like for instance C compiler deal with really large texts that have thousands lines of code?
If you're going to use a recursive descent parser, then you will inevitably run into an input which exceeds the call stack depth. This problem is ameliorated by languages like Java which are capable of controlling their own stack depth, so that there is a controllable result like a StackOverflowException. But it's still a real problem.
Parser generators like Yacc/Bison and Java Cup use a bottom-up LALR(1) algorithm which uses an explicit stack for temporary storage, rather than using the call stack for that purpose. That means that the parsers have to manage storage for the parser stack (or use a container ADT from the host language's standard library, if there is one), which is slightly more complex. But you don't have to deal with that complexity; it's built in to the parser generator.
There are several advantages of the explicit stack for the parser generator:
It's easier to control maximum stack size;
The maximum stack size is (usually) only limited by available memory;
It's probably more memory efficient because control flow information doesn't need to be kept in stack frames.
Still, it's not a panacea. A sufficiently complicated expression will exceed any fixed stack size, and that can be lead to certain programs being unparseable. Furthermore, if you take advantage of the flexibility mentioned in the second point above ("only limited by available memory"), you may well find that your compiler is terminated unceremoniously by an OOM process (or a segfault) rather than being able to respond to a more polite out-of-memory exception (depending on OS and configuration, of course).
As to:
How do other compilers, like for instance C compiler deal with really large texts that have thousands lines of code?
Having thousands of lines of code is not a problem if you use a repetition operator in your grammar (or, in the case that you are using an LALR(1) parser, that your grammar is left-recursive). The problem arises, as you note in your question, when you have texts with thousands of nested blocks. And the answer is that many C compilers don't deal gracefully with such texts. Here's a simple experiment with gcc:
$ # A function which generates deeply-nested C programs
$ type deep
deep is a function
deep () {
n=$1;
printf "%s\n%s\n %s\n" '#include <stdio.h>' 'int main(void) {' 'int a0 = 0;';
for ((i=0; i<n; ++i))
do
printf '%*s{ int a%d = a%d + 1;\n' $((i+1)) '' $((i+1)) $i;
done;
printf '%*sprintf("%%d\\n", a%d);\n' $n '' $n;
for ((i=0; i<n; ++i))
do
printf "%s" '}';
done;
printf "%s\n" '}'
}
$ deep 3
#include <stdio.h>
int main(void) {
int a0 = 0;
{ int a1 = a0 + 1;
{ int a2 = a1 + 1;
{ int a3 = a2 + 1;
printf("%d\n", a3);
}}}}
$ # For small depths, GCC is OK with that.
$ deep 3 | gcc -x c - && ./a.out
3
$ # Let's go deeper:
$ deep 10 | gcc -x c - && ./a.out
10
$ deep 100 | gcc -x c - && ./a.out
100
$ deep 1000 | gcc -x c - && ./a.out
1000
$ deep 10000 | gcc -x c - && ./a.out
10000
$ # Ka-bang. (Took quite a long time, too.)
$ deep 100000 | gcc -x c - && ./a.out
gcc: internal compiler error: Segmentation fault (program cc1)
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-7/README.Bugs> for instructions.
Without the nested blocks, gcc is still slow but can handle the program:
$ type big
big is a function
big ()
{
n=$1;
printf "%s\n%s\n %s\n" '#include <stdio.h>' 'int main(void) {' 'int a0 = 0;';
for ((i=0; i<n; ++i))
do
printf ' int a%d = a%d + 1;\n' $((i+1)) $i;
done;
printf ' printf("%%d\\n", a%d);\n' $n;
printf "%s\n" '}'
}
$ big 3
#include <stdio.h>
int main(void) {
int a0 = 0;
int a1 = a0 + 1;
int a2 = a1 + 1;
int a3 = a2 + 1;
printf("%d\n", a3);
}
$ $ big 3|gcc -x c - && ./a.out
3
$ big 10000|gcc -x c - && ./a.out
10000
$ big 100000|gcc -x c - && ./a.out
100000
You can define your grammar in ABNF syntax and give it to TGS* to parser it iteratively - without the use of the thread dedicated stack for recursion. The parser generator generates parsers that run iteratively for all of its operations: lexing, parsing, tree construction, tree to string conversion, tree iteration and tree destruction.
The parser at runtime, can also give you the tree building information with events only, then you can build your tree as you want (or do any calculation without any tree). In this case, when you parse with events (a deterministic parser grammar without explicit tree building), if you have enough operative memory to hold the depth of the parsing rules, you can practically "stream" any input regardless of its size.
The deterministic grammar in ABNF (RFC 5234) like syntax is this:
alternative = concatenation *('|' concatenation)
concatenation = 1* kleene-closure
kleene-closure = atomic 0*1 '*'
atomic = '(' alternative ')' / letter
letter = 'a'-'z' / 'A'-'Z'
This grammar however has one letter per item, and for input as "ab" you will get two atomic nodes with one letter per node. If you want to have more letters then maybe this grammar will do:
alternative = concatenation *('|' *ws concatenation)
concatenation = element *(ws 0*1 element)
element = primary 0*1 '*'
primary = '(' *ws alternative ')' / identifier
identifier = 1*('a'-'z' / 'A'-'Z')
ws = %x20 / %x9 / %xA / %xD
You can read that as: an alternative is made of one or more concatenations separated by |. A concatenation is one or more elements separated by at least one white space character. An element may end in * and can be an alternative in scopes or an identifier, which in turn is one or more letters. White space is space, tab, new line or carriage return. If you want to have more complex identifiers you may use this:
identifier = (letter / '_') *(letter / '_' / digit)
letter = 'a'-'z' / 'A'-'Z'
digit = '0'-'9'
*I work on that project.
From an answer by kvb about how to call implicit conversion operators:
let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)
I've known F# for a while but I just don't know how to parse the implementation here. What is (^a or ^b)? And the stuff after that? Please go over what each part represents grammatically.
^a or ^b means literally "^a or ^b".
The colon : means "has" or "contained in", depending on how you look at it.
So the whole expression (^a or ^b) : (static member op_Implicit : ^a -> ^b) means "static member named "op_Implicit" that has type ^a -> ^b and is defined on either type ^a or type ^b". This whole expression ultimately evaluates to a function of type ^a -> ^b.
Then, the x placed to the right of that expression means "function application", just like in the usual F# syntax.
So the whole thing taken together would mean "on type ^a or type ^b, find a static member named "op_Implicit" that has type ^a -> ^b, and apply that member to argument x".
For a bit more discussion of statically resolved constraints, see this answer or this MSDN article.
What does "^" mean when it's in front of a type?
Example:
int : ^T -> int
string : ^T -> string
this indicates an Statically Resolved Type Parameter
from MSDN:
A statically resolved type parameter is a type parameter that is
replaced with an actual type at compile time instead of at run time.
They are preceded by a caret (^) symbol.
so it's very similar to 'T but you can use it to give member constraints and the compiler will resolve them at compile-time (obviously) - usually you are just using inline and the type-inference will work it out for you - but there are some quite advanced tricks (for example FsControl) out there using this (not often used) feature
example
let inline add a b = a + b
val inline add :
a: ^a -> b: ^b -> ^c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
will add such a constraint to indicate that this will work with all numeric types (it will add an member constraint to an static operator (+))
very simple examples:
let myfun x = x
Here in the intellisense it says "x: 'a -> 'a". In the FSI it says "x: 'a -> 'a"
let inline myfun x = x
Here in the intellisense it says "x: 'a -> 'a". In the FSI it says "x: 'a -> 'a" <<<< why not ^a?
let inline myfun (x: 'b) = x
Here in the intellisense it says "x: 'b -> 'b". In the FSI it says "x: 'b -> 'b"
let inline myfun (x: ^b) = x
Here in the intellisense it says "x: 'b -> 'b". In the FSI it says "x: ^b -> ^b" <<<< different
Since the intellisense never shows ^b, should I look for ^b as an indicator of "statically resolved" in FSI?
Does inline guarantee "statically resolved"?
Inline does allow but does not force statically resolved types, that's why in case 2. it remains the same as in case 1.
I think in most cases type inference is smart enough to guess if the type should really be statically resolved, even if you don't specify the ^.
For example if you change your function body to sqrt x in case 3. you'll get
> let inline myfun (x: 'b) = sqrt x;;
val inline myfun : ^b -> ^a when ^b : (static member Sqrt : ^b -> ^a)
I personally always try not to specify types explicitly at first try, then I check if I'm happy with the inference, if I'm not then I try adding inline, but not the hat types.
Why intellisense shows sometimes something different? that's probably a small bug.
I am trying to explore the type of operators such as :: in F# interactive.
But I get these kinds of messages:
Unexpected symbol '::' in expression. Expected ')' or other token.
even if I surround it with (::).
I do it like this:
> let inline showmecons a b = a :: b;;
val inline showmecons : 'a -> 'a list -> 'a list
or
> let inline showmepow a b = a ** b;;
val inline showmepow :
^a -> ^b -> ^a when ^a : (static member Pow : ^a * ^b -> ^a)
You'll see the type of usual operators if you surround them with parentheses:
> (+);;
val it : (int -> int -> int) = <fun:it#4-5>
Unfortunatelly, this restricts the type of the operator to one specific type - F# Interactive doesn't print the polymorphic definition (with constraints). You can use the workaround suggested by Stephen (and define a new inline function) to see that.
The reason why it doesn't work for :: is that :: is actually a special syntactic construct (defined directly in the F# specification).
This is pretty old, but I'm learning F# and also wanted to figure this out.
Looking at the F# specification on page 32, we see that symbolic keywords also have a compiled name in F#. The equivalent compiled name for :: is op_ColonColon, which actually accepts tuples:
> op_ColonColon;;
val it : arg0:'a * arg1:'a list -> 'a list = <fun:clo#22-5>`
Using :: to define an inline function will give us a curried cons function, which is misleading, I believe.