2017-02-02 3 views
0

У меня есть Лекс и программа YACC, чтобы создать переключатель анализатор, который должен производить то, что следующий образом:программы Lex для коммутатора

switch(var) { 
    case 0: z=cost0; 
      break; 

    case N: z=costN; 
      break; 
    default: z=costD; 
      break; 
    } 

и пропускание 2 значения по умолчанию (позволяет сказать, что 1 и 2 соответственно), которые сохраняются в переменных x и y, каждый из них будет передан в ключ val, и будут проверены все условия N, поэтому z должна хранить переменную для значения найденного условия и печатать ее. но я не могу написать основную функцию моего YACC для организации ввода x и y и печати z. здесь мои программы:

Lex:

%{ 
    #include"ma1.tab.h" 
    %} 
    alpha [a-zA-Z] 
    digit [0-9] 
    %% 
    [ \t\n] 
    switch      return SWITCH; 
    int       return INT; 
    case       return CASE; 
    break      return BREAK; 
    default      return DEFAULT; 
    {digit}+      return NUM; 
    {alpha}({alpha}|{digit})* return ID; 
    .       return yytext[0]; 
    %% 

YACC:

%{ 
    #include<stdio.h> 
    #include<stdlib.h> 
    %} 
    %token ID NUM SWITCH CASE DEFAULT BREAK INT 
    %right '=' 
    %% 
    program: varassign switchstm {printf("Input accepted.\n");exit(0);} 
      ; 
    varassign: INT vardef ‘;’ 
    ; 
    vardef : ID '=' NUM | ID '=' NUM varassign {$1=$3;} 
    ; 
    switchstm: SWITCH '(' ID ')' '{' block '}' 
      ; 
    block: caselist 
      | caselist defaultstm 
      ; 
    caselist: casestm | casestm caselist ; 

    casestm: CASE NUM ':' assign ';' BREAK ';' 
      ; 

    defaultstm : DEFAULT ':' assign ';' BREAK ';' 
      ; 
    assign : ID'='NUM {$1=$3} 
    %% 
    main() 
    { 
    printf("Enter the exp: "); 
    yyparse(); 
    } 

но когда я запускаю в результате a.out файл, он просто ничего не делает! поэтому моя проблема заключается в том, чтобы обойти код, чтобы получить 2 целых числа и получить их, производя по одному z за каждый. Спасибо заранее.

+0

Что вы пробовали? Является ли фрагмент кода на языке C в вашем вопросе кодом, который вы хотите проанализировать? –

+0

Да. на самом деле мне нужно сгенерировать синтаксический анализатор для этой цели, и я сделал 2 необходимых файла lex и YACC, которые я прикрепляю ниже, где первая часть является лексическим анализатором, а вторая - генератором парсера (на самом деле я скомпилировал оба, и я создал синтаксический анализатор прямо сейчас, но главный() YACC() не является полным, чтобы принимать входные данные x и y и искать соответственно в случаях переключения и возврата z, и я не знал, как это сделать!) : –

+0

это мой файл lex: % { #include "ma1.tab.ч» %} альфа [A-Za-Z] цифры [0-9] %% [\ т \ п] переключатель возврата ПЕРЕКЛЮЧАТЕЛЬ; INT INT возврата; случай обратном случае, возврат перерыва BREAK; по умолчанию возврат DEFAULT; {цифра} + NUM возврата;. {альфа} ({альфа} | {цифра}) * возврат ID; вернуть yytext [0]; %% –

ответ

1

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

Если вы хотите что-то сделать с программой (оцените ее? Переведите в машинный код? Bytecode?), Вам нужно будет добавить действия в файл .y, чтобы взять маркеры, отсканированные и создающие полезные структуры данных и/или выход.

Ваш первый шаг будет иметь дело с маркерами NUM и ID, так как они имеют связанные значения. Вы должны определить %union в коде YACC для хранения значений:

%union { 
    int num; 
    char *id; 
} 

объявить лексемы, как использовать эти типы:

%token<num> NUM 
%token<id> ID 

и имеют ЛЕКС код возврата этих значений:

{digit}+      { yylval.num = atoi(yytext); return NUM; } 
{alpha}({alpha}|{digit})* { yylval.id = strdup(yytext); return ID; } 

с этим вы можете начать добавлять действия в код yacc, чтобы что-то делать.

+0

Спасибо за ответ. Очень хорошо, но я все еще не могу понять, как вернуть lex эти значения. я должен включить 2 строки внутри области согласования маркеров или у меня должен быть главный() в моем лексике? –

+0

Это действие соответствия токенов для второй секунды вашего '.l' файла. У вас есть только одна «главная» в вашей программе. –

+0

сделал, как сказал, но все же у меня нет никаких действий от a.out! –

Смежные вопросы