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__':
# from emis_funky_funktions import cur2, flip
# from build_oracle import print_oracle_table_enum, oracle_table
@ -324,20 +340,19 @@ if __name__ == '__main__':
from build_oracle import oracle_table
from parse import parser
from lex import tokenize
import sys
with open('sample.cnf') as file:
lexemes = unwrap_r(tokenize(LEX_TABLE, [Tok.Whitespace], Tok.Eof, file.read()))
oracle_table_ = oracle_table(p_instance(Tok), p_instance(Variable), GRAMMAR) #type:ignore
parser_ = parser(oracle_table_, flip(cur2(getattr))('token'), Variable.Start)
maybe_ast = parser_(lexemes)
match maybe_ast:
case Ok([Ok(ast)]):
print('\n'.join(' or '.join(str(t) for t in c) for c in ast))
case Ok([Err(err)]):
print(err)
case Ok(huh):
print('Unexpected end result: ', huh)
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}')
if len(sys.argv) == 2:
with open(sys.argv[1]) as file:
match lex_and_parse(file.read()):
case Ok(Ok(ir)):
print('\n'.join(' or '.join(str(t) for t in c) for c in ir))
case Ok(Err(err)):
print(err)
exit(102)
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}')
exit(101)
else:
print(f'Usage: python {sys.argv[0]} <cnf-file-to-parse>')
exit(100)