как создать парсер с antlr4 target golang без посетителей и ходоков

#go #antlr #antlr4

#Вперед #antlr #antlr4

Вопрос:

Я пытаюсь написать небольшой парсер с целью golang, но без использования посетителей или ходоков, но я не могу найти какой-либо пример кода для построения моего парсера.

Например, ниже приведен грамматический код, который я пытаюсь воспроизвести с помощью golang:

 # Expr.g4:
grammar Expr;
@header {
}
@parser::members {

def eval(self, left, op, right):
    if   ExprParser.MUL == op.type:
        return left * right
    elif ExprParser.DIV == op.type:
        return left / right
    elif ExprParser.ADD == op.type:
        return left   right
    elif ExprParser.SUB == op.type:
        return left - right
    else:
        return 0
}

stat:   e NEWLINE           {print($e.v);}
    |   ID '=' e NEWLINE    {self.memory[$ID.text] = $e.v}
    |   NEWLINE                   
    ;

e returns [int v]
    : a=e op=('*'|'/') b=e  {$v = self.eval($a.v, $op, $b.v)}
    | a=e op=(' '|'-') b=e  {$v = self.eval($a.v, $op, $b.v)}
    | INT                   {$v = $INT.int}    
    | ID
      {
id = $ID.text
$v = self.memory.get(id, 0)
      }
    | '(' e ')'             {$v = $e.v}       
    ; 
MUL : '*' ;
DIV : '/' ;
ADD : ' ' ;
SUB : '-' ;
ID  :   [a-zA-Z]  ;      // match identifiers
INT :   [0-9]  ;         // match integers
NEWLINE:'r'? 'n' ;     // return newlines to parser (is end-statement signal)
WS  :   [ t]  -> skip ; // toss out whitespace
  

И это тестовый код python для него:

 # test_expr.py:
import sys
from antlr4 import *
from antlr4.InputStream import InputStream

from ExprLexer import ExprLexer
from ExprParser import ExprParser

if __name__ == '__main__':
    parser = ExprParser(None)
    parser.buildParseTrees = False
    parser.memory = {}  # how to add this to generated constructor?

    line = sys.stdin.readline()
    lineno = 1

    while line != '':
        line = line.strip()

        istream = InputStream(line   "n")
        lexer = ExprLexer(istream)
        lexer.line = lineno
        lexer.column = 0
        token_stream = CommonTokenStream(lexer)
        parser.setInputStream(token_stream)
        parser.stat()

        line = sys.stdin.readline()
        lineno  = 1
  

Может кто-нибудь, пожалуйста, опубликовать пример кода golang, который эквивалентен приведенному выше python и встроенному коду?

Комментарии:

1. Не могли бы вы опубликовать свою собственную реализацию Go и задать конкретный вопрос об этом? Прямо сейчас вы просто просите кого-то другого написать все это за вас.

2. Проблема в том, что у меня нет примера кода, на котором можно было бы основывать мою собственную 1-ю версию. Например, в соответствии с определением eval() и его использованием в «$ v = self.eval(…)», К какому классу будет принадлежать функция eval и т. Д.? Я не ищу кого-то, кто написал бы мой код для меня, я просто ищу образец кода, на котором можно основать свой собственный синтаксический анализатор. Если что-то подобное где-то существует (даже для другой грамматики), если вы можете просто указать мне на эту ссылку, я могу начать работать на основе этого.

3. В ANTLR 4 есть посетители и слушатели, поэтому вы, вероятно, можете найти только типичные образцы, подобные этому. Почему вы должны придерживаться действий (вещей в {})? Это наследие предыдущих версий ANTLR (2/3), поэтому его используют только старые образцы.

4. Есть ли ссылка, по которой я могу получить эквивалент golang всех примеров Java из книги? Этого будет достаточно для меня, чтобы начать работу над этим.

5. @BartKiers: Я сделал первый шаг при написании кода и столкнулся с проблемой компилятора при доступе к значениям, возвращаемым компонентами грамматики. Я опубликовал более конкретный вопрос по этой теме — 64842665. Не могли бы вы помочь с этим? После того, как я преодолею это препятствие, я могу снова вернуться к этому вопросу.