我正在尝试使用 bison 和 flex 为自定义的类似 pascal 的语言制作编译器,但我最终得到了根据我的自定义语法应该正确的程序的语法错误。
我的自定义语法:
<program> ::= program id
<block>
<block> ::= {
<sequence>
}
<sequence> ::= <statement> ( ; <statement> )*
<brackets-seq> ::= { <sequence> }
<brack-or-stat> ::= <brackets-seq> |
<statement>
<statement> ::= ε |
<assignment-stat> |
<if-stat> |
<while-stat>
<assignment-stat> ::= id := <expression>
<if-stat> ::= if (<condition>)
<brack-or-stat>
<elsepart>
<elsepart> ::= ε |
else <brack-or-stat>
<while-stat> ::= while (<condition>)
<brack-or-stat>
<expression> ::= <optional-sign> <term> ( <add-oper> <term>)*
<term> ::= <factor> (<mul-oper> <factor>)*
<factor> ::= constant |
(<expression>) |
id
<condition> ::= <boolterm> (and <boolterm>)*
<boolterm> ::= <boolfactor> (or <boolfactor>)*
<boolfactor> ::= not [<condition>] |
[<condition>] |
<expression> <relational-oper> <expression>
<relational-oper> ::= == | < | > | <> | <= | >=
<add-oper> ::= + | -
<mul-oper> ::= * | /
<optional-sign> ::= ε | <add-oper>
我在野牛上的语法实现:
%{
#include <stdio.h>
#include <string.h>
int yylex(void);
void yyerror(char *s);
%}
%union {
int i;
char *s;
};
%token <i> INTEGERNUM
%token PROGRAM;
%token OR;
%token AND;
%token NOT;
%token IF;
%token ELSE;
%token WHILE;
%token PLUS;
%token MINUS;
%token MUL;
%token DIV;
%token LSB;
%token RSB;
%token LCB;
%token RCB;
%token LEFTPAR;
%token RIGHTPAR;
%token ID;
%token INT;
%token ASSIGN;
%token ISEQUAL;
%token LTHAN;
%token GTHAN;
%token NOTEQUAL;
%token LESSEQUAL;
%token GREATEREQUAL;
%left '+' '-'
%left '*' '/'
%%
program:
PROGRAM ID block
;
block:
LCB RCB
|LCB sequence RCB
;
sequence:
statement ';'sequence
|statement ';'
;
bracketsSeq:
LCB sequence RCB
;
brackOrStat:
bracketsSeq
|statement
;
statement:
assignmentStat
|ifStat
|whileStat
|
;
assignmentStat:
ID ':=' expression
ifStat:
IF LEFTPAR condition RIGHTPAR brackOrStat elsepart
;
elsepart:
ELSE brackOrStat
|
;
whileStat:
WHILE LEFTPAR condition RIGHTPAR brackOrStat
;
expression:
addOper expression
|expression addOper expression
|term
;
term:
term mulOper term
|factor
;
factor:
INT
|LEFTPAR expression RIGHTPAR
|ID
;
condition:
condition AND condition
|boolterm
;
boolterm:
boolterm OR boolterm
|boolfactor
;
boolfactor:
NOT LSB condition RSB
|LSB condition RSB
|expression relationalOper expression
;
relationalOper:
ISEQUAL
|LTHAN
|GTHAN
|NOTEQUAL
|LESSEQUAL
|GREATEREQUAL
;
addOper:
PLUS
|MINUS
;
mulOper:
MUL
|DIV
;
optionalSign
|addOper
;
%%
int main( int argc, char **argv )
{
extern FILE *yyin;
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
do
yyparse();
while(!feof(yyin));
}
我的 flex 实现非常简单,我只为所需的每个符号或标识符返回标记。
在以下简单程序上使用我的实现:
program circuit
{
a:=b;
}
我最终得到一个语法错误。:=
根据我使用的调试打印,特别是当解析到达点后:
$ ./a.exe verilog.txt
text = program
text = circuit val = circuit
text = {
text = a val = a
text = :=
syntax error
这是我第一次使用 flex 和 bison,所以我猜我对 bison 的原始语法执行错误,因为在./bison.exe -dy comp.y
我得到命令之后:
野牛冲突 64 移位/减少
任何想法都会有所帮助。谢谢!