dateutil python pyparsing

python - dateutil - Depuración de la gramática de creación



python dateutil pypi (1)

Estoy creando un analizador para un lenguaje de programación imaginario llamado C-- (no el lenguaje C-- real). Llegué a la etapa en la que necesito traducir la gramática del idioma en algo que Pyparsing pueda aceptar. Desafortunadamente, cuando llego a analizar mi cadena de entrada (lo cual es correcto y no debería causar un error en el Pyparsing), no se está analizando correctamente. Me temo que esto se debe a errores en mi gramática, pero cuando estoy iniciando Pyparsing por primera vez, parece que no puedo ver dónde me estoy equivocando.

He subido la gramática que estoy traduciendo desde here para que la gente pueda leerla.

EDITAR: Actualizado con el consejo de Paul.

Esta es la gramática que tengo actualmente (las dos líneas principales de la definición de Sintaxis son terriblemente malas de mi parte, lo sé):

# 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 he cometido algún error al traducir la gramática y qué mejoras podría hacer para simplificarla mientras me adhiero a la gramática que he recibido.

EDIT 2: actualizado para incluir el nuevo error.

Aquí está la cadena de entrada que estoy analizando:

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 recibo cuando ejecuto mi 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


1) Cambie Literal("if") a Keyword("if") (y así sucesivamente, hasta Literal("void") ), para evitar que coincida con el primer "si" de una variable llamada "ifactor" .

2) los nums , los alphas y los alphanums no son expresiones, son cadenas que se pueden usar con la clase de palabras para definir algunos conjuntos típicos de caracteres al definir "palabras" como "un número es una palabra compuesta de números", o "un identificador es una palabra que comienza con un alfa, seguido de cero o más alfanums". Así que en lugar de:

number = nums identifier = alphas + OneOrMore(alphanums)

usted quiere

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

3) En lugar de Combine , creo que quieres Group . Use Combine cuando desee que los tokens emparejados sean contiguos sin espacios en blanco intermedios, y concatenará los tokens y los devolverá como una sola cadena. Combine se utiliza a menudo en casos como este:

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

Sin Combine , el análisis "3.14" devolvería la lista de cadenas [''3'', ''.'', ''14''] , así que agregamos Combine para que el resultado analizado para realnum sea ''3.14'' (que luego podría pasar a un acción de análisis para convertir al valor flotante real 3.14 ). Combine no aplique espacios en blanco no nos impide analizar de forma accidental ''The answer is 3. 10 is too much.'' y pensando que el "3. 10" representa un número real.

4) Esto no debería causar su error, pero su cadena de entrada tiene muchos espacios adicionales. Si consigues que tu gramática funcione, deberías poder analizar "int x;" tan bien como "int x ;" .

Espero que algunos de estos consejos te pongan en marcha. ¿Has leído algún artículo o tutorial en línea? Y por favor mire los ejemplos en línea. Tendrá que comprender bien cómo Word , Literal , Combine , etc. realizan sus tareas de análisis individuales.

5) Ha implementado incorrectamente las definiciones recursivas para el término y la declaración. En lugar de asignarles '''' , escriba:

term = Forward() statement = Forward()

Luego, cuando vaya a definirlos realmente con sus definiciones recursivas, use el operador << (y asegúrese de incluir el RHS en () ).

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

here puede encontrar un ejemplo de un analizador recursivo y una presentación sobre el uso básico de los parámetros: consulte la sección titulada "Listas de análisis" para obtener más información paso a paso sobre cómo se maneja la recursión.