help-bison
[Top][All Lists]
Advanced

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

Software based character UART using Yacc (Bison) grammar ...


From: Jamie Risk
Subject: Software based character UART using Yacc (Bison) grammar ...
Date: Tue, 27 Sep 2005 22:24:24 -0400
User-agent: Mozilla Thunderbird 1.0.6 (Windows/20050716)

I've been trying to develop a small software based character UART. Eight (8) bit characters have one start bit (a zero) one stop bit (a one) and one odd bit of parity. Idle states are a one, so getting 100's of ones in a row is acceptable. The acceptable format is:

/* Yacc /Bison Grammar for acceptable character UART formatting */
BIT: ZERO
     | ONE;

CHARS:
           | CHARS CHAR
           | CHARS ONE;

CHAR: ZERO BIT BIT BIT BIT  BIT BIT BIT BIT  BIT ONE;

My problem with the grammar above is that I can't satisfactorily handle an erroneous ZERO token for a stop bit. I've tried to modifiy the "CHAR" rule:

CHAR : ZERO BIT BIT BIT BIT  BIT BIT BIT BIT  BIT ONE
          | ZERO error;

The above modified rule I'd hoped would (in the case of an error) discard the first ZERO, and 'push' the remaining 10 characters (the nine BIT tolkens plus the erred ZERO stop bit token) back to wherever for a new stab at the parsing. Instead, far more of the BIT values are skipped then I'd hoped for.

Suggestions? The entire file is posted below, has been tested with Bison and compiled.
- Jamie



%debug
%error-verbose
%locations
%verbose
%{
#include <stdio.h>
#include <malloc.h>

int yylex(void);
int yyerror (char const *s);
%}
%token EO_IN ZERO ONE


%%

CHARS   :
       | CHARS CHAR
       | CHARS ONE
       {
         /* Indicate we're skipping a one (acceptable to the protocol) */
         printf("1");
       }
       ;

BIT     : ZERO
| ONE ;

CHAR    : ZERO  BIT BIT BIT BIT   BIT BIT BIT BIT   BIT  ONE
       {
         printf("\n\r0 %d%d%d%d%d%d%d%d %d 1\n\r",($2)?1:0,
                                                  ($3)?1:0,
                                                  ($4)?1:0,
                                                  ($5)?1:0,
                                                  ($6)?1:0,
                                                  ($7)?1:0,
                                                  ($8)?1:0,
                                                  ($9)?1:0,
                                                  ($10)?1:0);

       }
       | ZERO error
       {
         /* This is meant to handle the case where
          *   CHAR -> ZERO  BIT BIT BIT BIT   BIT BIT BIT BIT   BIT  ZERO
          * Everything accept the first ZERO should be reprocessed.
          */
         /* Indicate we're skipping a zero (protocol error) */
         printf("0");
       }
;
%%

/* ****************************************************************** */
/*                                                                    */
/*  yylex()                                                           */
/*                                                                    */
/* ****************************************************************** */
int yylex(void)
{
 static int i = 0;
 static int data;

 switch(--i)
 {
   default: i &= 7;
   case 7 : if (1 != scanf("%x", & data)) return EO_IN;
   case 6 :
   case 5 :
   case 4 :
   case 3 :
   case 2 :
   case 1 :
   case 0 :
            if ( data & (1 << i) )
            {
              return ONE;
            }
            else
            {
              return ZERO;
            }
 }
} /* yylex() */

/* ****************************************************************** */
/*                                                                    */
/*  yyerror()                                                         */
/*                                                                    */
/* ****************************************************************** */
int yyerror (char const *s)
{
 return fprintf (stderr, "\n\r%s", s);
} /* yyerror() */

/* ****************************************************************** */
/*                                                                    */
/*  main()                                                            */
/*                                                                    */
/* ****************************************************************** */
int main(int argc, char ** argv)
{
/* any argument supplied on the command line will invoke the debug instrumenting */
 yydebug = (argc > 1);

 return printf("\n\rReturn %d\n\r", yyparse());
} /* main() */









reply via email to

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