aboutsummaryrefslogtreecommitdiff
path: root/compilador/parse/decl.py
diff options
context:
space:
mode:
Diffstat (limited to 'compilador/parse/decl.py')
-rw-r--r--compilador/parse/decl.py102
1 files changed, 102 insertions, 0 deletions
diff --git a/compilador/parse/decl.py b/compilador/parse/decl.py
new file mode 100644
index 0000000..73f8580
--- /dev/null
+++ b/compilador/parse/decl.py
@@ -0,0 +1,102 @@
+from typing import List, cast, Optional
+from more_itertools import peekable
+
+from tabla import Token, LexToken
+from parse.base import BaseParser
+from errors import Error
+from parse.type import ParseType
+from parse.ident import ParseIdent
+from parse.expr import ParseExpr, Expr
+from astree.decl import DeclGlobal, DeclFunc, Decl
+
+class ParseDecl:
+ def __init__(self, parser: BaseParser):
+ self.parser = parser
+
+ def decl_global(self) -> (DeclGlobal | Error):
+ # Tipo
+ _type = ParseType(self.parser)._type()
+ if type(_type) is Error:
+ return _type
+
+ # Identificador
+ ident = ParseIdent(self.parser).ident()
+ if type(ident) is Error:
+ return ident
+
+ # =
+ init: Optional[Expr] = None
+ eq = self.parser._try(Token.EQUAL)
+ if eq:
+ # Expresión
+ init = ParseExpr(self.parser).expr()
+ if type(init) is Error:
+ return init
+
+ return DeclGlobal(ident = ident,
+ _type = _type,
+ init = init)
+
+ def decl_func(self) -> (DeclFunc | Error):
+ # funcion
+ tok = self.parser.want(Token.FUNCTION)
+ if type(tok) is Error:
+ return tok
+
+ # Tipo
+ _type = ParseType(self.parser)._type()
+ if type(_type) is Error:
+ return _type
+
+ # Identificador
+ ident = ParseIdent(self.parser).ident()
+ if type(ident) is Error:
+ return ident
+
+ # Prototipo
+ proto = ParseType(self.parser).prototype()
+ if type(proto) is Error:
+ return proto
+
+ # ;
+ # semicolon = self.parser.want(Token.SEMICOLON)
+ # if type(semicolon) is Error:
+ # return semicolon
+ # self.parser.unlex()
+
+ return DeclFunc(ident = ident,
+ prototype = proto,
+ body = None)
+
+ # Parses a declaration.
+ def decl(self) -> (Decl | Error):
+ toks = [Token.BOOLEAN, Token.CHAR, Token.INT, Token.STRING, Token.VOID]
+ _next = self.parser.peek(*toks)
+ decl: Optional[Decl] = None
+ if not _next:
+ decl = self.decl_func()
+ else:
+ decl = self.decl_global()
+
+ if type(decl) is Error:
+ return decl
+
+ # ;
+ semicolon = self.parser.want(Token.SEMICOLON)
+ if type(semicolon) is Error:
+ return semicolon
+
+ return decl
+
+ # Parses the declarations for a sub-parser.
+ def decls(self) -> (List[Decl] | Error):
+ decls: List[Decl] = []
+ while not self.parser.peek(Token.EOF):
+ # print(self.parser.peek())
+ # print(next(self.parser.iterador))
+ decl = self.decl()
+ if type(decl) is Error:
+ return decl
+ decls.append(decl)
+
+ return decls