Last active
May 7, 2024 10:21
-
-
Save worldbeater/4938db8596e276b16c840e741707e12e to your computer and use it in GitHub Desktop.
Parses a subset of 1C into Python tuple-based AST. Uses peco.py, see https://github.com/true-grue/peco
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from peco import * | |
from pprint import pprint | |
def toloc(f, sep='\n'): | |
n = f.__code__.co_argcount - 1 | |
def parse(s): | |
lineno = s.data.count(sep, 0, s.pos) + 1 | |
pos = len(s.stack) - n | |
part = f(*s.stack[pos:], (lineno, 0)) | |
return s._replace(stack=s.stack[:pos] + (part,)) | |
return parse | |
ws = many(space) | |
tok = lambda f: memo(seq(ws, f)) | |
skip = lambda c: tok(sym(c)) | |
op = lambda c: tok(cite(sym(c))) | |
keywords = seq(alt( | |
skip('Функция'), | |
skip('КонецФункции'), | |
skip('Возврат'), | |
skip('Для'), | |
skip('По'), | |
skip('Цикл'), | |
skip('КонецЦикла'), | |
skip('Новый')), | |
npeek(letter)) | |
mkbop = toloc(lambda a, o, b, loc: (o, a, b, loc)) | |
mknum = toloc(lambda x, loc: ('const', x, loc)) | |
mkvar = toloc(lambda x, loc: ('var', x, loc)) | |
mkapp = toloc(lambda fun, args, loc: ('call', fun, ('args', *args, loc), loc)) | |
mkind = toloc(lambda src, ind, loc: ('index', src, ind, loc)) | |
mkmem = toloc(lambda src, mem, loc: ('member', src, mem, loc)) | |
mkass = toloc(lambda target, value, loc: ('assign', target, value, loc)) | |
mknew = toloc(lambda name, loc: ('new', name, loc)) | |
mkfor = toloc(lambda counter, lower, upper, body, loc: ('for', counter, lower, upper, ('body', *body, loc), loc)) | |
mkfun = toloc(lambda name, args, body, loc: ('func', name, ('params', *args, loc), ('body', *body, loc), loc)) | |
mkret = toloc(lambda val, loc: ('ret', val, loc)) | |
integer = alt(seq(range_of('1', '9'), many(digit)), sym('0')) | |
fractional = seq(sym('.'), some(digit)) | |
num = seq(cite(seq(integer, opt(fractional))), mknum) | |
var = seq(npeek(keywords), cite(seq(letter, many(alt(letter, digit))))) | |
expr = lambda s: expr(s) | |
term = lambda s: term(s) | |
fact = lambda s: fact(s) | |
attr = lambda s: attr(s) | |
stmt = lambda s: stmt(s) | |
attr = left(alt( | |
seq(attr, skip('.'), seq(tok(var), mkvar), mkmem), | |
seq(attr, skip('['), expr, skip(']'), mkind), | |
seq(attr, skip('('), group(opt(list_of(expr, skip(',')))), skip(')'), mkapp), | |
seq(tok(var), mkvar))) | |
fact = left(alt( | |
seq(skip('Новый'), seq(tok(var), mkvar), mknew), | |
seq(skip('('), expr, skip(')')), | |
tok(num), | |
attr)) | |
term = left(alt(seq(term, op('*'), fact, mkbop), | |
seq(term, op('/'), fact, mkbop), | |
fact)) | |
expr = left(alt(seq(expr, op('+'), term, mkbop), | |
seq(expr, op('-'), term, mkbop), | |
term)) | |
stmt = left(alt( | |
seq(skip('Возврат'), expr, skip(';'), mkret), | |
seq(skip('Для'), tok(var), skip('='), expr, skip('По'), expr, skip('Цикл'), | |
group(seq(stmt, many(stmt))), | |
skip('КонецЦикла'), skip(';'), mkfor), | |
seq(skip('Функция'), tok(var), skip('('), group(opt(list_of(tok(var), skip(',')))), skip(')'), | |
group(seq(stmt, many(stmt))), | |
skip('КонецФункции'), skip(';'), mkfun), | |
seq(attr, skip('='), expr, skip(';'), mkass), | |
seq(attr, skip(';')))) | |
def ast(code): | |
state = parse(code, seq(many(stmt), ws)) | |
return state.stack[-1] | |
CODE = ''' | |
Функция ВыполнитьПредсказание(Тета, Объекты) | |
Выводы = Новый СписокЗначений; | |
Для НомерСтроки = 0 По Объекты.Количество() - 1 Цикл | |
СкалярноеПроизведение = 0; | |
Для НомерСтолбца = 0 По Объекты[НомерСтроки].Значение.Количество() - 1 Цикл | |
СкалярноеПроизведение = | |
СкалярноеПроизведение + | |
Объекты[НомерСтроки].Значение[НомерСтолбца].Значение * | |
Тета[НомерСтолбца].Значение; | |
КонецЦикла; | |
Выводы.Добавить(СкалярноеПроизведение); | |
КонецЦикла; | |
Предсказания = Новый СписокЗначений; | |
Для НомерСтроки = 0 По Выводы.Количество() - 1 Цикл | |
Предсказания.Добавить(1 / (1 + Exp(1 - Выводы[НомерСтроки].Значение))); | |
КонецЦикла; | |
Возврат Предсказания; | |
КонецФункции; | |
'''.strip() | |
pprint(ast(CODE)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment