Распознавание шаблона вызова функции с Flex / Lex - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь написать компилятор Cminus (C-subset), но мой профессор требует, чтобы мы могли обрабатывать функции input() и output() как системные вызовы (в последнем семестре мы реализовали процессор RISC, который может справиться с этими инструкциями).

Для части input() мне удалось сделать это правильно с первой попытки (просто сделать шаблон, который соответствует "input()"), но проблема возникает с output(). Так как эта функция должна принимать массив или переменную в качестве аргумента, я предполагаю, что в шаблонах Lex мне нужно что-то подобное (ссылаясь на то, что я прочитал здесь ):

digito          [0-9]
numero          {digito}+
letra           [a-zA-Z]
identificador   {letra}+({letra}|{digito})*
input           "input()"
outputStart     "output("
outputSimple    {identificador}
outputComplex   {identificador}"["identificador"]"
outputEnd       ")"
output          {outputStart} ({outputSimple} | {outputComplex}){outputEnd}

Но у меня есть следующее определение в моей грамматике:

type: INT | VOID;
fun_decl: type ID LPAREN params RPAREN comp_decl;

где ID - токен, передаваемый от Лекса к Бизону, когда он соответствует строке identificador

Моя проблема в том, что сопоставляется только fun_decl, но я отвлекся.

Подводя итог, как мне сопоставить output(var) или output(array[i]) с шаблоном? Это вообще возможно?

Edit1: Прочитав ответ @rici, мне удалось придумать этот код для производства, отодвинув все от Lex / Flex, касаясь только Bison-YACC (остальная часть кода опущена для ясности):

ativacao    : id LPAREN args RPAREN
                {   
                    if(strcmp($1->attr.name, "output") == 0)
                    {
                        /*code for output system call*/
                    }
                    else if(strcmp($1->attr.name, "input") == 0)
                    {
                        /*code for input system call*/
                    } else{
                        /*code for other function activations*/
                    }
                }
            ;

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Учитывая, что у вас есть продукт для распознавания объявлений функций:

fun_decl: type ID LPAREN params RPAREN comp_decl;

Кажется разумным, что у вас есть продукт для распознавания вызовов функций:

expr     : /* ... */
         | ID LPAREN arguments RPAREN

arguments: /* empty */
         | exprs
exprs    : expr
         | exprs COMMA expr

Это охватывает грамматическую часть. Попытка сделать что-либо из этого в лексере нарушает четкое различие между лексическим анализом и анализом, которое вы, возможно, захотите рассмотреть. (Также, как вы обнаружили, это окажется невозможным.)

В ваших семантических действиях вам необходимо проверить, что такое ID в вызове функции, и вставить соответствующий код, если он окажется системным вызовом.

0 голосов
/ 27 июня 2018

А как насчет array[0] или array[1]? Они разрешены? Я не вижу, как fun_dec1 может соответствовать, потому что здесь не указан тип возвращаемого значения - я думаю, у вас есть определение вызова функции в вашей грамматике, конечно, это будет соответствовать этому?

Одного определения грамматики вызова функции должно быть достаточно, я не уверен, почему вы пытаетесь жестко закодировать input / output функций в грамматике.

...