Proyecto 1. Analizador léxico y sintáctico
Enviado por Angel Gabriel Negrete Valadez • 23 de Febrero de 2023 • Trabajo • 3.481 Palabras (14 Páginas) • 39 Visitas
[pic 1] [pic 2]
Carrera:
Ingeniería en Software
Asignatura:
Compiladores e intérpretes
Proyecto 1. Analizador léxico y sintáctico
Alumno(a)s:
ANGEL GABRIEL NEGRETE VALADEZ
PAUL ALEJANDRO RAMÍREZ ZARAGOZA
MÓNICO ASAEL TORRES GARCÍA
Profesor:
Dr. Sergio Valadez Godínez
Fecha de entrega: 23/02/23
Instrucciones:
A partir de un caso práctico, elaborar un reporte que incluya:
a) Requerimientos del lenguaje de programación
b) Tipos de palabras y puntuación que proporcionará el lenguaje
c) Especificación del tipo de flujo de control
d) Tipos de datos a admitir
e) Estructura general del lenguaje de programación
f) Lexemas, categorías léxicas y tokens
g) Expresiones regulares
h) Código fuente en JFlex
i) Gramáticas libres de contexto
j) Código fuente en Yacc
k) Conclusiones
l) Bibliografía
a) Requerimientos del lenguaje de programación |
El lenguaje de programación “Sixty”, planteado como una alternativa de propósito general, deberá cumplir con los siguientes requerimientos para su primera versión:
|
b) Tipos de palabras y puntuación que proporcionará el lenguaje |
Palabras reservadas.
Identificadores.
Literales.
Operadores. Igual que en matemáticas, realizan una acción específica:
Operadores en Sixty, por orden de precedencia . [ ] ( ) ++ – ! * / % + - < > <= >= == != === & | Delimitadores. Símbolos utilizados como separadores de las distintas construcciones de un lenguaje de programación(esto es, los signos de puntuación de un lenguaje de programación).
Comentarios. Aclaración que el programador incluye en el texto del programa para mejorar su inteligibilidad. En Sixty habrá 2 tipos de comentarios:
|
c) Especificación del tipo de flujo de control |
IF-ELSE if(expresión){ bloque de código } else { bloque de código } WHILE whl(expresión){ bloque de código } FOR for(int variable = x; expresión; incremento ó decremento){ bloque de código } ELIF if(expresión){ bloque de código } elif (expresión { bloque de código } |
d) Tipos de datos a admitir |
BOOLEAN Sirve para definir tipos de datos booleanos. Aquellos que tienen valor de “true” o “false”. Ocupan 1 bit de información. CHAR Es un tipo de dato que representa a un carácter Unicode sencillo de 16 bits. STRING Objetos de Sixty que representan cadenas de caracteres. Los caracteres se codifican usando Unicode. INT Es un tipo de dato de 32 bits con un signo para almacenar valores numéricos. Cuyo valor mínimo es -2^31 y valor máximo 2^31-1. FLOAT Es un tipo de dato para almacenar números en coma flotante con precisión simple de 32 bits. |
e) Estructura general del lenguaje de programación |
Para comenzar a escribir un programa en Sixty deberá declararse la función principal, a partir de la cual comenzará la ejecución de manera secuencial de cada sentencia. Para ilustrar de una mejor manera, el siguiente código sería el necesario para realizar el famoso “Hola mundo” en este lenguaje. func main(): int{ write(“Hola mundo”); ret 0; } |
f) Lexemas, categorías léxicas y tokens |
g) Expresiones regulares |
identificador: id=([a-zA-Z_][a-zA-Z0-9]*) comentario multilínea: "/*"([^*]|"*"+[^/*])*"*"+"/" comentario: "//".*\r?\n espacio en blanco: [ \t\r\f]+ línea en blanco: \n break: brk else: else false for if else if: elif null function: func return: ret character: chr string: str boolean: bool integer: int float: flt true void while: whl ( ) [ ] { } ; : ! * / // % + - < \^ <= > >= == != & | = += -= , . integer: [0-9]+ float: [0-9]*"."[0-9]*([eE][+-]?[0-9]+)? ([0-9]+)([eE][+-]?([0-9]+)) \"([^\"]|(\\.))*\" '([^']|(\\.))*' . |
h) Código fuente en JFlex |
%% %int id=([a-zA-Z_][a-zA-Z0-9]*) %% "/*"([^*]|"*"+[^/*])*"*"+"/" { sixty.comment(); } "//".*\r?\n { sixty.comment(); } [ \t\r\f]+ { sixty.whitespace(); } \n { sixty.newline(); } "brk" { return sixty.scan(parser.BREAK); } "else" { return sixty.scan(parser.ELSE); } "false" { return sixty.scan(parser.BOOLLIT); } "for" { return sixty.scan(parser.FOR); } "if" { return sixty.scan(parser.IF); } "elif" { return sixty.scan(parser.ELIF); } "null" { return sixty.scan(parser.NULLVAL); } "func" { return sixty.scan(parser.FUNCTION); } "ret" { return sixty.scan(parser.RETURN); } "chr" { return sixty.scan(parser.CHAR); } "str" { return sixty.scan(parser.STRING); } "bool" { return sixty.scan(parser.BOOL); } "int" { return sixty.scan(parser.INT); } "flt" { return sixty.scan(parser.FLOAT); } "true" { return sixty.scan(parser.BOOLLIT); } "void" { return sixty.scan(parser.VOID); } "whl" { return sixty.scan(parser.WHILE); } "(" { return sixty.scan(sixty.ord("("));} ")" { return sixty.scan(sixty.ord(")"));} "[" { return sixty.scan(sixty.ord("["));} "]" { return sixty.scan(sixty.ord("]"));} "{" { return sixty.scan(sixty.ord("{"));} "}" { return sixty.scan(sixty.ord("}"));} ";" { return sixty.scan(sixty.ord(";"));} ":" { return sixty.scan(sixty.ord(":"));} "!" { return sixty.scan(sixty.ord("!"));} "*" { return sixty.scan(sixty.ord("*"));} "/" { return sixty.scan(sixty.ord("/"));} "//" { return sixty.scan(sixty.ord("//"));} "%" { return sixty.scan(sixty.ord("%"));} "+" { return sixty.scan(sixty.ord("+"));} "-" { return sixty.scan(sixty.ord("-"));} "<" { return sixty.scan(sixty.ord("<"));} "\^" { return sixty.scan(sixty.ord("^"));} "<=" { return sixty.scan(parser.LESSTHANOREQUAL);} ">" { return sixty.scan(sixty.ord(">"));} ">=" { return sixty.scan(parser.GREATERTHANOREQUAL);} "==" { return sixty.scan(parser.ISEQUALTO);} "!=" { return sixty.scan(parser.NOTEQUALTO);} "&" { return sixty.scan(parser.LOGICALAND);} "|" { return sixty.scan(parser.LOGICALOR);} "=" { return sixty.scan(sixty.ord("=")); } "+=" { return sixty.scan(parser.INCREMENT); } "-=" { return sixty.scan(parser.DECREMENT); } "," { return sixty.scan(sixty.ord(",")); } "." { return sixty.scan(sixty.ord(".")); } {id} { return sixty.scan(parser.IDENTIFIER); } [0-9]+ { return sixty.scan(parser.INTLIT); } [0-9]*"."[0-9]*([eE][+-]?[0-9]+)? { return sixty.scan(parser.FLOATLIT); } ([0-9]+)([eE][+-]?([0-9]+)) { return sixty.scan(parser.FLOATLIT); } \"([^\"]|(\\.))*\" { return sixty.scan(parser.STRINGLIT); } '([^']|(\\.))*' { return sixty.scan(parser.CHARLIT); } . { sixty.lexErr("unrecognized character"); } |
i) Gramáticas libres de contexto |
FieldDecl: VarDecls : Type ; Type: INT | FLOAT | BOOL | STRING | CHAR | Name Name: IDENTIFIER | QualifiedName QualifiedName: Name . IDENTIFIER VarDecls: VarDeclarator | VarDecls , VarDeclarator VarDeclarator: IDENTIFIER | VarDeclarator [ ] MethodReturnVal : Type | VOID MethodDecl: MethodHeader Block MethodHeader: FUNCTION MethodDeclarator : MethodReturnVal MethodDeclarator: IDENTIFIER ( FormalParmListOpt ) FormalParmListOpt: FormalParmList FormalParmList: FormalParm | FormalParmList , FormalParm FormalParm: VarDeclarator : Type ArgListOpt: ArgList Block: { BlockStmtsOpt } BlockStmtsOpt: BlockStmts BlockStmts: BlockStmt | BlockStmts BlockStmt BlockStmt: LocalVarDeclStmt | Stmt LocalVarDeclStmt: LocalVarDecl ; LocalVarDecl: VarDecls : Type Stmt: Block | ; | ExprStmt | BreakStmt | ReturnStmt | | IfThenStmt | IfThenElseStmt | IfThenElseIfStmt | WhileStmt | ForStmt ExprStmt: StmtExpr ; StmtExpr: Assignment | MethodCall | InstantiationExpr IfThenStmt: IF ( Expr ) Block IfThenElseStmt: IF ( Expr ) Block ELSE Block IfThenElseIfStmt: IF ( Expr ) Block ElseIfSequence | IF ( Expr ) Block ElseIfSequence ELSE Block ElseIfSequence: ElseIfStmt | ElseIfSequence ElseIfStmt ElseIfStmt: ELIF ( Expr ) Block | ELSE IfThenStmt WhileStmt: WHILE ( Expr ) Stmt ForStmt: FOR ( ForInit ; ExprOpt ; ForUpdate ) Block ForInit: StmtExprList | LocalVarDecl ExprOpt: Expr ForUpdate: StmtExprList StmtExprList: StmtExpr | StmtExprList , StmtExpr BreakStmt: BREAK ; | BREAK IDENTIFIER ; ReturnStmt: RETURN ExprOpt ; Primary: Literal | ( Expr ) | FieldAccess | MethodCall Literal: INTLIT | FLOATLIT | BOOLLIT | STRINGLIT | CHARLIT | NULLVAL InstantiationExpr: Name ( ArgListOpt ) ArgList: Expr | ArgList , Expr FieldAccess: Primary . IDENTIFIER MethodCall: Name ( ArgListOpt ) | Name { ArgListOpt } | Primary . IDENTIFIER ( ArgListOpt ) | Primary . IDENTIFIER { ArgListOpt } PostFixExpr: Primary | Name UnaryExpr: - UnaryExpr | ! UnaryExpr | PostFixExpr MulExpr: UnaryExpr | MulExpr * UnaryExpr | MulExpr / UnaryExpr | MulExpr % UnaryExpr AddExpr: MulExpr | AddExpr + MulExpr | AddExpr - MulExpr RelOp: LESSTHANOREQUAL | GREATERTHANOREQUAL | < | > RelExpr: AddExpr | RelExpr RelOp AddExpr EqExpr: RelExpr | EqExpr ISEQUALTO RelExpr | EqExpr NOTEQUALTO RelExpr CondAndExpr: EqExpr | CondAndExpr LOGICALAND EqExpr CondOrExpr: CondAndExpr | CondOrExpr LOGICALOR CondAndExpr Expr: CondOrExpr | Assignment Assignment: LeftHandSide AssignOp Expr LeftHandSide: Name | FieldAccess AssignOp: = | INCREMENT | DECREMENT |
j) Código fuente en Yacc |
%token BREAK ELSE FOR IF INT RETURN VOID WHILE FLOAT ELIF %token IDENTIFIER FUNCTION CHAR STRING BOOL %token INTLIT CHARLIT STRINGLIT BOOLLIT NULLVAL FLOATLIT %token LESSTHANOREQUAL GREATERTHANOREQUAL %token ISEQUALTO NOTEQUALTO LOGICALAND LOGICALOR %token INCREMENT DECREMENT %% FieldDecl: VarDecls ':' Type ';' ; Type: INT | FLOAT | BOOL | STRING | CHAR | Name ; Name: IDENTIFIER | QualifiedName ; QualifiedName: Name '.' IDENTIFIER ; VarDecls: VarDeclarator | VarDecls ',' VarDeclarator ; VarDeclarator: IDENTIFIER | VarDeclarator '[' ']' ; MethodReturnVal : Type | VOID ; MethodDecl: MethodHeader Block ; MethodHeader: FUNCTION MethodDeclarator ':' MethodReturnVal ; MethodDeclarator: IDENTIFIER '(' FormalParmListOpt ')' ; FormalParmListOpt: FormalParmList | ''; FormalParmList: FormalParm | FormalParmList ',' FormalParm ; FormalParm: VarDeclarator ':' Type ; ArgListOpt: ArgList | ; Block: '{' BlockStmtsOpt '}' ; BlockStmtsOpt: BlockStmts | ; BlockStmts: BlockStmt | BlockStmts BlockStmt ; BlockStmt: LocalVarDeclStmt | Stmt ; LocalVarDeclStmt: LocalVarDecl ';' ; LocalVarDecl: VarDecls ':' Type; Stmt: Block | ';' | ExprStmt | BreakStmt | ReturnStmt | | IfThenStmt | IfThenElseStmt | IfThenElseIfStmt | WhileStmt | ForStmt ; StmtWithoutTrailingSubstatement: ; ExprStmt: StmtExpr ';' ; StmtExpr: Assignment | MethodCall | InstantiationExpr ; IfThenStmt: IF '(' Expr ')' Block ; IfThenElseStmt: IF '(' Expr ')' Block ELSE Block ; IfThenElseIfStmt: IF '(' Expr ')' Block ElseIfSequence | IF '(' Expr ')' Block ElseIfSequence ELSE Block ; ElseIfSequence: ElseIfStmt | ElseIfSequence ElseIfStmt ; ElseIfStmt: ELIF '(' Expr ')' Block | ELSE IfThenStmt ; WhileStmt: WHILE '(' Expr ')' Stmt ; ForStmt: FOR '(' ForInit ';' ExprOpt ';' ForUpdate ')' Block ; ForInit: StmtExprList | LocalVarDecl | ; ExprOpt: Expr | ; ForUpdate: StmtExprList | ; StmtExprList: StmtExpr | StmtExprList ',' StmtExpr ; BreakStmt: BREAK ';' | BREAK IDENTIFIER ';' ; ReturnStmt: RETURN ExprOpt ';' ; Primary: Literal | '(' Expr ')' | FieldAccess | MethodCall ; Literal: INTLIT | FLOATLIT | BOOLLIT | STRINGLIT | CHARLIT | NULLVAL ; InstantiationExpr: Name '(' ArgListOpt ')' ; ArgList: Expr | ArgList ',' Expr ; FieldAccess: Primary '.' IDENTIFIER ; MethodCall: Name '(' ArgListOpt ')' | Name '{' ArgListOpt '}' | Primary '.' IDENTIFIER '(' ArgListOpt ')' | Primary '.' IDENTIFIER '{' ArgListOpt '}' ; PostFixExpr: Primary | Name ; UnaryExpr: '-' UnaryExpr | '!' UnaryExpr | PostFixExpr ; MulExpr: UnaryExpr | MulExpr '*' UnaryExpr | MulExpr '/' UnaryExpr | MulExpr '%' UnaryExpr ; AddExpr: MulExpr | AddExpr '+' MulExpr | AddExpr '-' MulExpr ; RelOp: LESSTHANOREQUAL | GREATERTHANOREQUAL | '<' | '>' ; RelExpr: AddExpr | RelExpr RelOp AddExpr ; EqExpr: RelExpr | EqExpr ISEQUALTO RelExpr | EqExpr NOTEQUALTO RelExpr ; CondAndExpr: EqExpr | CondAndExpr LOGICALAND EqExpr ; CondOrExpr: CondAndExpr | CondOrExpr LOGICALOR CondAndExpr ; Expr: CondOrExpr | Assignment ; Assignment: LeftHandSide AssignOp Expr ; LeftHandSide: Name | FieldAccess ; AssignOp: '=' | INCREMENT | DECREMENT ; |
k) Conclusiones |
Con la culminación de este reporte el cual contiene información sobre cómo se elaboró un compilador para un lenguaje llamado Sixty, se puede concluir que se ha realizado un trabajo exhaustivo y detallado. El equipo encargado del desarrollo ha mostrado habilidades técnicas y una comprensión profunda de los principios fundamentales de los compiladores y la programación. El software Sixty ha sido diseñado para procesar programas escritos en este lenguaje y convertirlos en un código ejecutable. El reporte describe con precisión el proceso de diseño e implementación del compilador, incluyendo la definición del lenguaje, el análisis léxico, sintáctico, semántico y la generación de código. Se puede observar que el equipo ha prestado atención a aspectos importantes como la eficacia y la eficiencia del compilador, la generación de mensajes de error claros y precisos, la compatibilidad con diferentes plataformas y la facilidad de uso. En general, el reporte demuestra que se ha realizado un trabajo serio y bien planificado en el desarrollo del compilador Sixty. Este compilador tiene el potencial de ser una herramienta valiosa para los programadores que trabajan con este lenguaje, ya que facilitará el proceso de creación y depuración de programas en Sixty. |
g) Bibliografía |
P. (s. f.). GitHub - PacktPublishing/Build-Your-Own-Programming-Language: Build Your Own Programming Language, published by Packt. GitHub. https://github.com/PacktPublishing/Build-Your-Own-Programming-Language |
...