"Abdulaziz Ghuloum" wrote:
>On Aug 3, 2009, at 8:36 AM, Marco Maggi wrote:
>
>>   One problem  that needs to  be solved is how  to access
>> parser  and   lexer  specific  state   when  loading  the
>> parser/lexer from a library.
>
> Why do the lexer and parser have state, and what does that
> state hold?

(silex)  and (lalr) define  the lexer  and the  parser using
rules like:

SOME-PATTERN (a-form-which-ends-in-a-closure)

and they generate tables which, somewhat, look like:

'#(---

   (lambda (some argument)
     (do-something-in-parser
       (a-form-which-ends-in-a-closure)))

   ---)

when the table is enclosed in a library it looks like:

(library (calc-parser)
  (export calc-parser)
  (import (rnrs) (lalr lr-driver) ---)
  (define calc-parser
    (lr-driver
      '#(---
         (lambda (some argument)
           (do-something-in-parser
             (a-form-which-ends-in-a-closure)))
         ---))))

  If    the     driver    is    meant     to    allow    it,
A-FORM-WHICH-ENDS-IN-A-CLOSURE can access SOME and ARGUMENT.
They have informations about the state of the driver itself;
for example, with (silex),  they provide the line and column
number counters.

  But that  is all; the libraries,  as they are  now, do not
allow  to hand to  the closures  lexer and  parser instances
specific state.

  (lalr) is designed to  allow direct evaluation of code, so
the calculator example has rules like:

(assign
   (ID ASSIGN expr) :
     (hashtable-set! (table-of-variables) $1 $3))

(expr (expr + expr)       : (+ $1 $3)
      (expr - expr)       : (- $1 $3)
      (expr * expr)       : (* $1 $3)
      (expr / expr)       : (/ $1 $3)
      (- expr (prec: uminus)) : (- $2)
      (ID) : (hashtable-ref (table-of-variables) $1 #f)

      (ID LPAREN args RPAREN) : (apply $1 $3)
      (NUM) : $1
      (LPAREN expr RPAREN) : $2)

which become lambdas like (for the addition):

(lambda (___stack ___sp ___goto-table ___push yypushback)
  (let* (($3 (vector-ref ___stack (- ___sp 1)))
         ($2 (vector-ref ___stack (- ___sp 3)))
         ($1 (vector-ref ___stack (- ___sp 5))))
    (___push 3 4 (+ $1 $3))))

  It  is  possible to  modify  the  generators  to make  the
closures  accept  custom arguments,  but  I  am not  looking
forward to it.  To use parameters is much easier.

  To build a  parse tree (I have not tried  it, yet), we can
modify the rules to:

(expr + expr) : (list + $1 $3)

so the nested evaluation of each closure builds the tree.

  But  (lalr) does  not allow  access to  the value  of each
evaluated  rule, and  it does  not return  the value  of the
outer expression  parsed; when it  receives the end-of-input
token, it  just returns nothing.   This could be  changed of
course,  because it  involves only  a change  in  the driver
(which  is  small  and   should  not  be  too  difficult  to
understand).  The  solution right now  is to make  the outer
rule store the result in a parameter.
-- 
Marco Maggi

Reply via email to