2010-06-30 13 views
10

yo estaba tratando de analizar Lisp sencilla/esquema similarconstrucción Lisp/Scheme-como con código de flexión/bisontes

E.g. (func a (b c d)) 

y construir un árbol de ella, I podría hacer el análisis sintáctico en C sin usar bison (es decir, usando solo flex para devolver tokens y construir el árbol con recursividad). Pero, con bison gramática, no estoy seguro de dónde agregar el código para construir la lista (es decir, la regla a asociar con la acumulación de terminal de símbolos y donde para enlazar una lista construida a nodo padre).

Mi gramática es similar a la de aquí: Lisp grammar in yacc la gramática es correcta y puede reconocer el código.

+1

Retuse de 'flex' a' gnu-flex' a pesar del consejo contrario aquí: http://meta.stackexchange.com/questions/26460/tag-for-two-flexes/26708#26708 simplemente porque es confundir a muchos visitantes del sitio para ver el icono de Adobe en la etiqueta. Espero que esto se solucione pronto. La mejor de las suertes para obtener una respuesta a su pregunta. – bernie

+5

Apenas necesitas flex o bison para analizar simples expresiones S. Debería ser capaz de codificar esto como un simple analizador de descenso recursivo con un lexer enrollado a mano para átomos, paréntesis y un patrón de espacio en blanco en algo así como cien líneas de C o menos. Los intérpretes originales de LISP sin duda lo hicieron con solo un poquito de código. –

+2

Ira: Es cierto que no es necesario un analizador sintáctico, pero el "lexer enrollado a mano" funciona solo para los subconjuntos de juguetes habituales con los que la gente suele terminar. Algunos Lisps/Schemes tienen tokens que pueden obtener * muy * peludos. Para su entretenimiento, aquí hay un ejemplo de una constante numérica válida en [Racket] (http://racket-lang.org/): '# e # x + e # s + e @ -e # l-e'. –

Respuesta

3

¿Ha intentado colocar el código para agregar un elemento a la lista actual en cada átomo y codificar para administrar un árbol de listas cuando procesa los corchetes? Parece que la forma más fácil a menos que corra en otros problemas:

listend: members ')'  { cur = cur->parent; } 
     | ')'    { cur = cur->parent; } 
     ; 

list: '(' listend   { cur = newList(cur);} 
    ; 

atom: ID     { appendAtom(cur, "ID"); } 
    | NUM     { appendAtom(cur, "NUM");} 
    | STR     { appendAtom(cur, "STR");} 
    ; 

Esto supone que está mantener un punto dominante en cada una struct lista.

+0

Hola Amoss, no lo había intentado con un puntero principal, intentaré este enfoque. Gracias. – vyom

+0

vjom: ¿Funcionó? Si es así, por favor, dale a Amoss su debido al aceptar la respuesta :) – Baggers

Cuestiones relacionadas