help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Identifying start of new rule


From: Test User
Subject: Identifying start of new rule
Date: Sat, 15 Jun 2013 02:33:26 -0500

Hello All,

I am trying to parse an arbitrary BNF file. My simple test file
test.txt file contains:

<procedure_declaration> ::= PROCEDURE <procedure_body>
<procedure_body> ::= BEGIN <statement> END
<statement> ::= PRINT "hello world"

In this grammar upper-case strings and strings in double-quotes are
terminal symbols. Lower-case strings in angle brackets are
non-terminal symbols. I am trying to implement the following grammar
(for rules in BNF) in my bison file:

<rule> ::= <name> "::=" <expansion>
<name> ::= < identifier >
<expansion> ::= <expansion> <expansion>
<expansion> ::= <expansion> "|" <expansion>
<expansion> ::= <name>
<expansion> ::= <terminal>

When I parse test.txt, I get:
Found name <procedure_declaration>
Found LITERAL_STRING: PROCEDURE
Found name <procedure_body>
Found name <procedure_body>
Success!
EEK, parse error!  Message: syntax error

I understand that the rule `<expansion> ::= <expansion> <expansion>'
*does* allow `PROCEDURE <procedure_body> <procedure_body>' to be
reduced to <rule>. However, the second <procedure_body> is followed by
::= (token EXPANDS_TO in my bison file) and is therefore the start of
a new rule and not part of a previous rule. How do I tell bison that
the second <procedure_body> is the start of a new rule?

I admit that I have not read the manual yet. I found someone's
tutorial in which he made up a short, useless sample language and I am
trying to adapt it to my needs. Please see my bison file test.y below.

Regards,
Test User

%{
#include <stdio.h>
#include <stdlib.h>

 extern  int yylex();
 extern  int yyparse();
 extern  FILE *yyin;

 void yyerror(const char *s);
 %}

%union {
  char cval;
  int ival;
  float fval;
  char *sval;
}

/* define the "terminal symbol" token types */
%token <sval> EXPANDS_TO
%token <cval> AT_SIGN
%token <cval> DOT
%token <cval> COMMA
%token <cval> EQUAL
%token <cval> LEFT_ROUNDB
%token <cval> RIGHT_ROUNDB
%token <cval> LEFT_SQUAREB
%token <cval> RIGHT_SQUAREB
%token <cval> LEFT_CURLYB
%token <cval> RIGHT_CURLYB
%token <cval> LEFT_ANGLEB
%token <cval> RIGHT_ANGLEB
%token <sval> IDENTIFIER
%token <sval> QUOTED_STRING
%token <sval> LITERAL_STRING
%token <fval> FLOAT
%token <ival> INTEGER
%token <cval> OR
%%

rule: name EXPANDS_TO expansion  { printf("Success!\n"); }

name: LEFT_ANGLEB IDENTIFIER RIGHT_ANGLEB { printf("Found name
%c%s%c\n", $1, $2, $3); }

expansion: expansion expansion ;

expansion: expansion OR expansion ;

expansion: name ;

expansion: terminal  ;

terminal: LITERAL_STRING { printf("Found LITERAL_STRING: %s\n", $1); }
%%
FILE *yyin;

int main(int argc, char *argv[])
{
  FILE *fpi = NULL;
  if (strcmp(argv[1], "-") == 0)
    fpi = stdin;
  else
    fpi = fopen(argv[1], "r");
  if (!fpi){
    fprintf(stderr, "I can't open %s\n", argv[1]);
    return -1;
  }
  yyin = fpi;
  do{
    yyparse();
  } while (!feof(yyin));
  return 0;

}

void yyerror(const char *s) {
  printf("EEK, parse error!  Message: %s\n", s);
    // might as well halt now:
    exit(-1);
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]