Pergunta

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

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

The problem seems to be in 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 variable program was defined this way:

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

but it doesn't work, it still waits for standard input characters.

The documentation lacks details, so we can't figure out how we can solve this.

Thank you

Foi útil?

Solução

You are very, very close to the solution! Well, sort of. But here's a start. Look at the original code, around where you were modifying 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 your (current-input-port) to your string port (BTW, don't call open-input-string more than once, since you create a new string port each time, each with independent cursors), but it's not the only place that actually uses (current-input-port).

Do you see it? It's actually in the (read-char) call! That function actually takes a port argument, defaulting to (current-input-port).

In fact, if you look above and search for instances of (read-char) and (peek-char), you'll notice that the use of (current-input-port) is pretty much baked into the whole make-lexer function. So you will need to change that.

I would suggest that you specify an input port to 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 don't forget to change your make-source-location call too:

(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.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top