Scheme - LALR parser generation - line input

We are trying to generate (in guile) a parser and lexer that read characters from a string instead of stdin.

We started modifying the example calculator included in the code at http://code.google.com/p/lalr-scm/source/browse/trunk/calc.scm?r=52

The problem is the following line:

(let* ((location (make-source-location "*stdin*" (port-line (current-input-port)) (port-column (current-input-port)) -1 -1)) 

We tried to define a new input port:

 (let* ((location (make-source-location "*stdin*" (port-line (open-input-string program)) (port-column (open-input-string program)) -1 -1)) 

and the program variable was defined as follows:

 (define program "int x = 2; int y = 0; y= x*(2+3);" ) 

but it does not work, it is still waiting for standard input characters.

There are no details in the documentation, so we cannot understand how we can solve this.

thanks

+4
source share
1 answer

You are very, very close to a solution! Well, sort of. But here is the beginning. Look at the source code where you modified it:

 (let* ((location (make-source-location "*stdin*" (port-line (current-input-port)) (port-column (current-input-port)) -1 -1)) (c (read-char))) ...) 

Here you changed all of your (current-input-port) to your string port (BTW, do not call open-input-string more than once, because each time each new port is created each with independent cursors), but this is not only a place that actually uses (current-input-port) .

Do you see it? It really is in a call (read-char) ! This function actually takes a port argument, the default is (current-input-port) .

In fact, if you look above and find instances of (read-char) and (peek-char) , you will notice that using (current-input-port) is pretty much baked into the whole make-lexer function. Therefore, you will need to change this.

I would suggest specifying an input port for the make-lexer function:

 (define* (make-lexer errorp #:optional (input (current-input-port))) ... 

then change all instances of (read-char) and (peek-char) to use the input port. Also remember to also change your make-source-location call:

 (let* ((location (make-source-location "*stdin*" (port-line input) (port-column input) -1 -1)) (c (read-char input))) ...) 

Now you can use (make-lexer errorp (open-input-string program)) and it should work. (I have not tested it.)

+2
source

Source: https://habr.com/ru/post/1446203/


All Articles