diff options
author | Iván Ávalos <avalos@disroot.org> | 2022-11-25 13:14:35 -0600 |
---|---|---|
committer | Iván Ávalos <avalos@disroot.org> | 2022-11-25 13:14:35 -0600 |
commit | 52d6d2107f14398ae59baaa893d596fb239c4679 (patch) | |
tree | 27f7170933fc0ecd57d7df5814517a7e3a7daad4 | |
parent | eb4a3019bc0251e5b2b8229679e3c65d61d55336 (diff) | |
download | javanol-52d6d2107f14398ae59baaa893d596fb239c4679.tar.gz javanol-52d6d2107f14398ae59baaa893d596fb239c4679.tar.bz2 javanol-52d6d2107f14398ae59baaa893d596fb239c4679.zip |
Ya funcionan decl_global y decl_func
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | compilador/nanoiter.py | 30 | ||||
-rw-r--r-- | compilador/parse/base.py | 9 | ||||
-rw-r--r-- | compilador/parse/decl.py | 12 | ||||
-rw-r--r-- | compilador/parse/expr.py | 2 | ||||
-rw-r--r-- | compilador/parse/type.py | 38 | ||||
-rw-r--r-- | compilador/parser.py | 2 | ||||
-rw-r--r-- | compilador/tabla.py | 6 | ||||
-rw-r--r-- | pruebas/sintaxis2.es | 6 |
9 files changed, 71 insertions, 38 deletions
@@ -1,2 +1,4 @@ __pycache__/ -*.tab
\ No newline at end of file +*.tab +*.gv +*.gv.pdf diff --git a/compilador/nanoiter.py b/compilador/nanoiter.py new file mode 100644 index 0000000..928522f --- /dev/null +++ b/compilador/nanoiter.py @@ -0,0 +1,30 @@ +from typing import Optional, NoReturn, List, TypeVar + +T = TypeVar('T') + +class NanoIter: + def __init__(self, l: List[T]): + self.i = -1 + self.l: List[T] = l + + def next(self) -> T: + if self.i == len(self.l): + raise StopIteration() + else: + self.i += 1 + return self.l[self.i] + + def get(self, i = None): + return self.l[self.i] if not i else self.l[i] + + def back(self) -> NoReturn: + if self.i <= 0: + self.i = -1 + else: + self.i -= 1 + + def peek(self) -> T: + if self.i == len(self.l): + raise StopIteration() + else: + return self.l[self.i + 1] diff --git a/compilador/parse/base.py b/compilador/parse/base.py index a8f6f8a..49742e6 100644 --- a/compilador/parse/base.py +++ b/compilador/parse/base.py @@ -7,12 +7,13 @@ from errors import Error from typing import NoReturn from more_itertools import seekable +from nanoiter import NanoIter from tabla import TablaLex, Token from errors import Error class BaseParser: - def __init__(self, iterador: seekable): - self.iterador: seekable = iterador + def __init__(self, iterador: NanoIter): + self.iterador: NanoIter = iterador ''' Requires the next token to have a matching ltok. Returns that token, or an error. ''' @@ -49,10 +50,10 @@ class BaseParser: return tok def lex(self): - return next(self.iterador) + return self.iterador.next() def unlex(self): - self.iterador.seek(-1) + self.iterador.back() ''' Returns a syntax error if cond is false and void otherwise ''' def synassert(self, cond: bool, msg: str) -> (Error | NoReturn): diff --git a/compilador/parse/decl.py b/compilador/parse/decl.py index 73f8580..4a752f0 100644 --- a/compilador/parse/decl.py +++ b/compilador/parse/decl.py @@ -54,7 +54,7 @@ class ParseDecl: return ident # Prototipo - proto = ParseType(self.parser).prototype() + proto = ParseType(self.parser).prototype(_type) if type(proto) is Error: return proto @@ -70,12 +70,16 @@ class ParseDecl: # Parses a declaration. def decl(self) -> (Decl | Error): - toks = [Token.BOOLEAN, Token.CHAR, Token.INT, Token.STRING, Token.VOID] - _next = self.parser.peek(*toks) + toks = [Token.BOOLEAN, Token.CHAR, Token.INT, Token.STRING, Token.VOID, Token.FUNCTION] + _next = self.parser.want(*toks) decl: Optional[Decl] = None - if not _next: + if type(_next) is Error: + return _next + elif _next.tipo is Token.FUNCTION: + self.parser.unlex() decl = self.decl_func() else: + self.parser.unlex() decl = self.decl_global() if type(decl) is Error: diff --git a/compilador/parse/expr.py b/compilador/parse/expr.py index a00f3d5..23b1a61 100644 --- a/compilador/parse/expr.py +++ b/compilador/parse/expr.py @@ -7,6 +7,6 @@ class ParseExpr: self.parser = parser def expr(self) -> Expr | Error: - next(self.parser.iterador) + self.parser.iterador.next() return diff --git a/compilador/parse/type.py b/compilador/parse/type.py index 27b83d3..06c68d0 100644 --- a/compilador/parse/type.py +++ b/compilador/parse/type.py @@ -16,48 +16,36 @@ class ParseType: return tok return BuiltinType(tok.tipo) - def prototype(self) -> (FuncType | Error): + def prototype(self, _type: Type) -> (FuncType | Error): params: List[FuncParam] = [] - # Tipo - tok = ParseType(self.parser)._type() - if type(tok) is Error: - return tok - _type = tok - # ( tok = self.parser.want(Token.L_PAREN) if type(tok) is Error: return tok - while True: - tok = self.parser._try(Token.R_PAREN) - if not tok: - break - + + while not self.parser._try(Token.R_PAREN): + # Tipo - tok = ParseType(self.parser)._type() - if type(tok) is Error: - return tok - __type: Type = tok + __type = ParseType(self.parser)._type() + if type(__type) is Error: + return __type # Identificador - tok = self.parser.want(Token.IDENT) - if type(tok) is Error: - return tok - name: str = tok + name = self.parser.want(Token.IDENT) + if type(name) is Error: + return name params.append(FuncParam(name = name, _type = __type)) # , - tok = self.parser._try(Token.COMMA) - if not tok: + if self.parser._try(Token.COMMA): continue # ) - tok = self.parser.want(Token.R_PAREN) - if type(tok) is Error: - return tok + if self.parser._try(Token.R_PAREN): + break return FuncType(result = _type, params = params) diff --git a/compilador/parser.py b/compilador/parser.py index 82ee3c8..99cabe7 100644 --- a/compilador/parser.py +++ b/compilador/parser.py @@ -19,5 +19,5 @@ class Parser: print (unit.message, file=sys.stderr) return 1 - pprint(self.unit) + pprint(unit) return 0 diff --git a/compilador/tabla.py b/compilador/tabla.py index d0a8ffe..fb76e08 100644 --- a/compilador/tabla.py +++ b/compilador/tabla.py @@ -2,7 +2,9 @@ import json, os from enum import Enum, auto from dataclasses import dataclass from typing import Any -from more_itertools import seekable +# from more_itertools import seekable + +from nanoiter import NanoIter reservadas = [ 'BOOLEAN', @@ -101,7 +103,7 @@ class TablaLex: return [t for t in self.tabla if t.nombre == nombre][0] def iterar(self): - return seekable(self.tabla) + return NanoIter(self.tabla) def actualizar(self, nombre: str, tok: LexToken): for i, t in enumerate(self.tabla): diff --git a/pruebas/sintaxis2.es b/pruebas/sintaxis2.es new file mode 100644 index 0000000..c89bee0 --- /dev/null +++ b/pruebas/sintaxis2.es @@ -0,0 +1,6 @@ +entero a = 10; +entero b = 20; +booleano c = verdadero; +caracter d; +funcion entero a (entero a, cadena b); +funcion caracter b (booleano a);
\ No newline at end of file |