Pregunta

Estoy construyendo un analizador para un imaginario lenguaje de programación llamado C-- (no la real C-- language).He llegado a la etapa donde tengo que traducir del lenguaje de la gramática en algo Pyparsing puede aceptar.Por desgracia, cuando me vienen a analizar mi cadena de entrada (lo cual es correcto y no debe causar Pyparsing a error) no analizar correctamente.Me temo que esto es debido a errores en la gramática, pero como estoy empezando Pyparsing por primera vez, me parece que no puede ver donde estoy pasando mal.

He subido la gramática que estoy traduciendo aquí que la gente lea.

EDITAR: Actualizado con el consejo de Pablo.

Esta es la gramática he actualmente tengo (las dos primeras líneas de la definición de Sintaxis son terriblemente mal de mí yo sepa):

# Lexical structure definition
ifS = Keyword('if')
elseS = Keyword('else')
whileS = Keyword('while')
returnS = Keyword('return')
intVar = Keyword('int')
voidKeyword = Keyword('void')
sumdiff = Literal('+') | Literal('-')
prodquot = Literal('*') | Literal('/')
relation = Literal('<=') | Literal('<') | Literal('==') | \
           Literal('!=') | Literal('>') | Literal('=>')
lbrace = Literal('{')
rbrace = Literal('}')
lparn = Literal('(')
rparn = Literal(')')
semi = Literal(';')
comma = Literal(',')
number = Word(nums)
identifier = Word(alphas, alphanums)

# Syntax definition
term = ''
statement = ''
variable    =   intVar + identifier + semi
locals      =   ZeroOrMore(variable)
expr        =   term | OneOrMore(Group(sumdiff + term))
args        =   ZeroOrMore(OneOrMore(Group(expr + comma)) | expr)
funccall    =   Group(identifier + lparn + args + rparn)
factor      =   Group(lparn + expr + rparn) | identifier | funccall | number
term        =   factor | OneOrMore(prodquot + factor)
cond        =   Group(lparn + expr + relation + expr + rparn)
returnState =   Group(returnS + semi) | Combine(returnS + expr + semi)
assignment  =   Group(identifier + '=' + expr + semi)
proccall    =   Group(identifier + lparn + args + rparn + semi)
block       =   Group(lbrace + locals + statement + rbrace)
iteration   =   Group(whileS + cond + block)
selection   =   Group(ifS + cond + block) | Group(ifS + cond + block + elseS + block)
statement   =   OneOrMore(proccall | assignment | selection | iteration | returnState)
param       =   Group(intVar + identifier)
paramlist   =   OneOrMore(Combine(param + comma)) | param
params      =   paramlist | voidKeyword
procedure   =   Group(voidKeyword + identifier + lparn + params + rparn + block)
function    =   Group(intVar + identifier + lparn + params + rparn + block)
declaration =   variable | function | procedure
program     =   OneOrMore(declaration)

Me gustaría saber si hay alguna de los errores que he cometido en la traducción de la gramática a través de y qué mejoras podría hacer para que sea simplificado, mientras que la adhesión a la gramática que me han dado.

EDIT 2: Actualizado para incluir el nuevo error.

Aquí está la cadena de entrada yo soy de análisis:

int larger ( int first , int second ) { 
if ( first > second ) { 
return first ; 
} else { 
return second ; 
} 
} 

void main ( void ) { 
int count ; 
int sum ; 
int max ; 
int x ; 

x = input ( ) ; 
max = x ; 
sum = 0 ; 
count = 0 ; 

while ( x != 0 ) { 
count = count + 1 ; 
sum = sum + x ; 
max = larger ( max , x ) ; 
x = input ( ) ; 
} 

output ( count ) ; 
output ( sum ) ; 
output ( max ) ; 
} 

Y este es el mensaje de error que tengo cuando se ejecuta el programa desde la Terminal:

/Users/Joe/Documents/Eclipse Projects/Parser/src/pyparsing.py:1156: SyntaxWarning: null string passed to Literal; use Empty() instead
other = Literal( other )
/Users/Joe/Documents/Eclipse Projects/Parser/src/pyparsing.py:1258: SyntaxWarning: null string passed to Literal; use Empty() instead
other = Literal( other )
Expected ")" (at char 30), (line:6, col:26)
None
¿Fue útil?

Solución

1) Cambiar Literal("if") a Keyword("if") (y así sucesivamente, hasta Literal("void")), para evitar la coincidencia de los principales "si" de una variable denominada "ifactor".

2) nums, alphas, y alphanums no son expresiones, que son cadenas de caracteres, que pueden ser usadas con la Palabra clase para definir algunos de los conjuntos de caracteres cuando la definición de "palabras" como "un número es una palabra compuesta de numérica", o "un identificador es una palabra que comience con un alfa, seguido por cero o más alphanums." Así que en lugar de:

number = nums
identifier = alphas + OneOrMore(alphanums)

quieres

number = Word(nums)
identifier = Word(alphas, alphanums)

3) en Lugar de Combine, Creo que usted desee Group.Uso Combine cuando desea que la coincidencia de los tokens para ser contiguas a no intervenir en los espacios en blanco, y concatenar las fichas y se les devolverá como una sola cadena. Combine a menudo se utiliza en casos como este:

realnum = Combine(Word(nums) + "." + Word(nums))

Sin Combine, análisis "3.14" quisiera regresar a la lista de cadenas ['3', '.', '14'], así que agregamos Combine de modo que el resultado analizado para realnum es '3.14' (que luego puede pasar a analizar la acción de convertir a la real flotante valor 3.14). Combines cumplimiento de no intervenir en los espacios en blanco también nos impide accidentalmente análisis 'The answer is 3. 10 is too much.' y el pensamiento del "3. 10" representa un número real.

4) Esto no debería causar su error, pero su cadena de entrada tiene muchas de espacios adicionales.Si usted recibe su gramática de trabajo, usted debe ser capaz de analizar "int x;" tan bien como "int x ;".

Esperanza de que algunos de estos consejos que te vas.Has leído alguna línea de pyparsing artículos o tutoriales?Y por favor, mirar a través de los ejemplos en línea.Usted necesita para obtener una buena idea de cómo Word, Literal, Combine, etc.realizar sus análisis de tareas.

5) Usted tiene mal implementado las definiciones recursivas de plazo y declaración.En lugar de asignar '' para ellos, escribir:

term = Forward()
statement = Forward()

Entonces, cuando usted va a definir realmente ellos con sus definiciones recursivas, el uso de la << operador (y asegúrese de adjuntar los RHS en ()'s).

term << (... term definition ...)
statement << (... statement definition ...)

Usted puede encontrar un ejemplo de un analizador recursiva aquí, y una presentación básica pyparsing uso aquí - vea la sección titulada "Análisis de las Listas" para obtener más paso a paso sobre cómo la recursividad que se maneja.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top