Add a combined lex+parse method

This commit is contained in:
Emi Simpson 2023-03-05 16:21:28 -05:00
parent 98253bb254
commit 9e6c7d504d
Signed by: Emi
GPG key ID: A12F2C2FFDC3D847

View file

@ -317,6 +317,22 @@ CSTerms := Comma <Term> <CSTerms>
:= ε := ε
""" """
def lex_and_parse(input: str) -> Result[Result[Sequence[Sequence[IRTerm]], GenIrError], Tuple[Lexeme[Tok], Collection[Tok]]]:
lexemes = unwrap_r(tokenize(LEX_TABLE, [Tok.Whitespace], Tok.Eof, input))
oracle_table_ = oracle_table(p_instance(Tok), p_instance(Variable), GRAMMAR) #type:ignore
parser_ = parser(oracle_table_, flip(cur2(getattr))('token'), Variable.Start)
match parser_(lexemes):
case Ok([Ok(ir)]):
return Ok(Ok(ir))
case Ok([Err(err)]):
return Ok(Err(err))
case Ok(huh):
raise Exception('Unexpected end result: ', huh)
case Err(e_tup):
return Err(e_tup) #type:ignore
raise Exception('Unreachable')
if __name__ == '__main__': if __name__ == '__main__':
# from emis_funky_funktions import cur2, flip # from emis_funky_funktions import cur2, flip
# from build_oracle import print_oracle_table_enum, oracle_table # from build_oracle import print_oracle_table_enum, oracle_table
@ -324,20 +340,19 @@ if __name__ == '__main__':
from build_oracle import oracle_table from build_oracle import oracle_table
from parse import parser from parse import parser
from lex import tokenize from lex import tokenize
import sys
with open('sample.cnf') as file: if len(sys.argv) == 2:
lexemes = unwrap_r(tokenize(LEX_TABLE, [Tok.Whitespace], Tok.Eof, file.read())) with open(sys.argv[1]) as file:
match lex_and_parse(file.read()):
oracle_table_ = oracle_table(p_instance(Tok), p_instance(Variable), GRAMMAR) #type:ignore case Ok(Ok(ir)):
parser_ = parser(oracle_table_, flip(cur2(getattr))('token'), Variable.Start) print('\n'.join(' or '.join(str(t) for t in c) for c in ir))
maybe_ast = parser_(lexemes) case Ok(Err(err)):
print(err)
match maybe_ast: exit(102)
case Ok([Ok(ast)]): case Err((Lexeme(token, text, line, col_start, col_end), expected)):
print('\n'.join(' or '.join(str(t) for t in c) for c in ast)) print(f'Parse error! Line {line}:{col_start}-{col_end}\n\nGot: {repr(text)}\nExpected: {expected}')
case Ok([Err(err)]): exit(101)
print(err) else:
case Ok(huh): print(f'Usage: python {sys.argv[0]} <cnf-file-to-parse>')
print('Unexpected end result: ', huh) exit(100)
case Err((Lexeme(token, text, line, col_start, col_end), expected)):
print(f'Parse error! Line {line}:{col_start}-{col_end}\n\nGot: {repr(text)}\nExpected: {expected}')