import abc
import enum
from typing import *
VarName = NewType('VarName', str) # A name of variable. Its type is int, sequence of int, etc.. For example, "a", "b", "f", and "ans" are VarName. However, "a_i" is not a VarName.
Expr = NewType('Expr', str) # An expr. The type is always int. For example, "n + 1", "a_i", "x", and "2 * x" are Expr.
[docs]class ItemNode(FormatNode):
name: VarName
indices: List[Expr]
def __init__(self, *, name: str, indices: Sequence[str] = []):
self.name = VarName(name)
self.indices = list(map(Expr, indices))
[docs]class NewlineNode(FormatNode):
pass
[docs]class SequenceNode(FormatNode):
items: List[FormatNode]
def __init__(self, *, items: Sequence[FormatNode]):
self.items = list(items)
[docs]class LoopNode(FormatNode):
size: Expr
name: VarName # TODO: rename `name` with `counter`
body: FormatNode
def __init__(self, *, size: str, name: str, body: FormatNode):
self.size = Expr(size)
self.name = VarName(name)
self.body = body
[docs]class SampleCase(NamedTuple):
input: bytes
output: bytes
[docs]class AnalyzerResources(NamedTuple):
url: Optional[str]
html: Optional[bytes]
input_format_string: Optional[str]
output_format_string: Optional[str]
sample_cases: Optional[List[SampleCase]]
[docs]class VarType(enum.Enum):
IndexInt = 'IndexInt'
ValueInt = 'ValueInt'
Float = 'Float'
String = 'String'
Char = 'Char'
# NegativeOne = 'NegativeOne'
[docs]class VarDecl(NamedTuple):
name: VarName
type: Optional[VarType]
dims: List[Expr]
bases: List[Expr]
depending: Set[VarName]
[docs]class ConstantDecl(NamedTuple):
name: VarName
value: str # For example, "1000000007", "Yes", "No". Not Expr type.
type: VarType
[docs]class OutputType(abc.ABC):
pass
[docs]class YesNoOutputType(OutputType):
name: Expr
yes: str
no: str
def __init__(self, *, name: Expr, yes: str, no: str):
self.name = name
self.yes = yes
self.no = no
[docs]class OneOutputType(OutputType):
name: Expr
type: Optional[VarType]
def __init__(self, *, name: Expr, type: Optional[VarType]):
self.name = name
self.type = type
[docs]class TwoOutputType(OutputType):
name1: Expr
type1: Optional[VarType]
name2: Expr
type2: Optional[VarType]
print_newline_after_item: bool
def __init__(self, *, name1: Expr, type1: Optional[VarType], name2: Expr, type2: Optional[VarType], print_newline_after_item: bool):
self.name1 = name1
self.type1 = type1
self.name2 = name2
self.type2 = type2
self.print_newline_after_item = print_newline_after_item
[docs]class VectorOutputType(OutputType):
name: VarName # This has VarName type instead of Expr type becuase it will be subscripted.
type: Optional[VarType]
subscripted_name: str # TODO: remove this variable. This has a string like "a[i]", but carrying source code is not responsibility of this class.
counter_name: VarName
print_size: bool
print_newline_after_size: bool
print_newline_after_item: bool
def __init__(self, *, name: VarName, type: Optional[VarType], subscripted_name: str, counter_name: VarName, print_size: bool, print_newline_after_size: bool, print_newline_after_item: bool):
self.name = name
self.type = type
self.subscripted_name = subscripted_name
self.counter_name = counter_name
self.print_size = print_size
self.print_newline_after_size = print_newline_after_size
self.print_newline_after_item = print_newline_after_item
[docs]class TopcoderType(enum.Enum):
Int = 'int'
Long = 'long'
Double = 'double'
String = 'String'
IntList = 'int[]'
LongList = 'long[]'
DoubleList = 'double[]'
StringList = 'String[]'
[docs]class TopcoderClassDefinition(NamedTuple):
class_name: str
method_name: str
formal_arguments: List[Tuple[TopcoderType, VarName]]
return_type: TopcoderType
[docs]class AnalyzerResult(NamedTuple):
resources: AnalyzerResources
input_format: Optional[FormatNode]
input_variables: Optional[Dict[VarName, VarDecl]]
output_format: Optional[FormatNode]
output_variables: Optional[Dict[VarName, VarDecl]]
constants: Dict[VarName, ConstantDecl]
output_type: Optional[OutputType]
topcoder_class_definition: Optional[TopcoderClassDefinition]
[docs]class TemplateAnalyzerGeneratorError(RuntimeError):
pass
[docs]class AnalyzerError(TemplateAnalyzerGeneratorError):
pass
[docs]class GeneratorError(TemplateAnalyzerGeneratorError):
pass