LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Blogs > rainbowsally
User Name
Password

Notices

Rate this Entry

flex test and new libLQ/mc2 upload

Posted 07-01-2012 at 09:57 AM by rainbowsally
Updated 07-03-2012 at 05:55 AM by rainbowsally

[Update: flex IS mind blown! ...

Update to the update. We MIGHT be able to use flex if we 'touch' the files before creating them.
]

Features:
  • New extended target built-ins for mc2 Makefiles
  • Hopeful work-around for flex's brain damage
  • Starting a collection of flex examples that work (at least once on MY system -- but I don't care to guarantee anything more than this)

We recommend the latest mc2 for generating the Makefile but you may be able to recreate it from the mini-template if you are familiar with make.

http://www.linuxquestions.org/questi...support-34783/

Flex experiments 1-3

These are working (i.e., corrected) examples from the flex manual with a few minor changes for various reasons.

Note the relative paths under the flex experiments build folder in the "file:" fields.

Also, if you're not using mc2, the binaries go into the builddir/bin folder. Type 'bin/test-NN' to run each one, assuming the build works for you.

WARNING: THE COMMENTS IN THE SOURCES ARE NOT DEFINITIVE - I'M HAVING AS MUCH TROUBLE AS YOU DID FIGURING THIS UNHOLY MESS OUT. THEY MAY BE CLUES AS TO THINGS TO TRY IF YOU HAVE PROBLEMS WITH YOUR OWN FLEX APPS AND THAT'S ALL THEY ARE AT THIS POINT.

file: mc2.def
purpose: makefile mini-template (requires libLQ-mc2 version 3.-07 or greater)
Code:
# mc2 makefile defs for a compilation of one source = one executable
# type of build.  

PREFIX = $(HOME)/usr32

OUTNAME = MULTI

SRCDIR = src
OBJDIR = o

BINDIR = bin

# compile function overrides
COMPILE = gcc -m32 -c -o # COMPILE <output_file> (for C, 32 bit, object)
#CFLAGS = -std=c99 -Wall -DBUILD_DIR=\"$(PWD)\" -g3 # -no-warn | -Wall # debug
CFLAGS = -std=c99 --no-warn -DBUILD_DIR=\"$(PWD)\" -O2 # -Wall  # optimized
INCLUDE = -I $(SRCDIR) -I $(PREFIX)/include -I /usr/include 

EXT_ALL = ext_all
EXT_CLEAN = ext_clean
EXT_UPDATE = ext_update

# link function overrides
LINK = gcc -m32 -o

# include a shotgun spread of libs here so all the files work
LDFLAGS = # -lgmp # -lLQ-qt
LIB = -L$(PREFIX)/lib -L/usr/lib 
 
semiclean:
  @rm -f $(OBJ)
  @rm -f *~ */*~ */*/*~ */*/*/*~

strip:
  @strip $(MAIN_FILES)
  @make semiclean

clean:  $(EXT_CLEAN)
  @rm -f $(MAIN_FILES)
  @rm -f $(OBJ)
  @rm -f *.kdevelop.pcs *.kdevses
  @rm -f *~ */*~ */*/*~ */*/*/*~ tmp.mak

#####################################################################
# these are new EXT_* functions not present in mc2 < 3.07 but can be 
# added manually to a makefile if you know how.

ext_clean:
  rm -f src/test-01.yyc
  rm -f src/test-02.yyc
  rm -f src/test-03.yyc
  
ext_all: force
  touch src/*.c
  flex --outfile="src/test-01.yyc" "src/test-01.l"
  flex --outfile="src/test-02.yyc" "src/test-02.l"
  flex --outfile="src/test-03.yyc" "src/test-03.l"

ext_update:
  rm -f main.kdevelop.filelist
  for i in src/*; do echo $$i >> main.kdevelop.filelist; done


force:

.PHONEY: force

file: src/test-01.c
purpose: flex output file loader
Code:
#include "test-01.yyc"

/* The C Code Section
After the terminating '%%' C code can be inserted in 
the file.  Both / *... * / and //... style comments are
accepted in the C-99 standard.
*/

// main.c -- skeleton created by new.main

#include <stdio.h>
#include <malloc.h>
#include <string.h>

// int num_lines, num_chars; - declared in the grammar file C header section

// yywrap is responsible for loading additional files if any.  It returns 0
// on success.  We don't include any files so we return 1 so ^D at the keyboard 
// on an empty line will exit the program instead of endless loop-ing.
int yywrap(void){return 1;}

//#define YY_NO_INPUT

void dbg(){} // for a non-moving breakpoint


int main(int argc, char** argv)
{
  dbg();
  printf("Test to use flex grammar file to read the number of lines and\n"
      "chars in input from the keyboard\n\n");
  
  printf("Enter some text and press Ctrl-D on an empty line to end\n");
  
  yylex(); // the scanner
  
  printf( "[# of lines = %d, # of chars = %d]\n",
          num_lines, num_chars );
  return 0;

}

file: src/test-01.h
purpose: source file
Code:
// test1.h

#ifndef test1_h
#define test1_h

// this doesn't appear to have any effect here?
// #define YY_SKIP_YYWRAP

#endif // test1_h

file: src/test-01.l
purpose: source file
Code:
/* Counts chars and lines in files

The Flex Header section, generally just comments.

Note: The following %{ %} are missing in the flex man 
page example this is based on.  This is where the variables 
are declared and there's no main() function for that example 
nor the yylex() usage nor a good explanation of what yywrap() 
really does. See test-01.c (the main() file).*/

/* C Declarations Section 

Declarations and includes go between %{ and %} markers at 
the start of a line. */
%{

int num_lines, num_chars;

%}

/* The Rules Section
The tokens and actions (the rules section) goes here 
between delimiting '%%' markers */
%%
\n      ++num_lines; ++num_chars;
.       ++num_chars;

file: src/test-02.c
purpose: flex output file loader
Code:
#include "test-02.yyc"

int usage(int errcode)
{
  printf(
      "Input a file or type text from the keyboard to scan for \n"
      "words that match Pascal-like syntax rules.\n");
  return errcode;
}

// also defines yywrap()
int yywrap() {return 1;}

// This no longer seems to be an issue with the 'touch' work around but 
// kept in case this is really part of the flex bug.
// ------------
// don't use the names argc and argv here or flex may choose the name of 
// the output file and clobber the one we've got.
int run(int nargs, char **args)
{
  if((nargs == 1) || (!strcmp(args[1], "--help")))
      return usage(0);
     
  ++args, --nargs;  /* skip over program name */
      if ( nargs > 0 )
        yyin = fopen( args[0], "r" );
      else
        yyin = stdin;
      yylex();
  return 0;
} 




//                                  WARNING
// If C Code section in the grammar file contains certain code such as main() or other 
// functions that contain the 'argc' and 'argv' names this file may get clobbered because 
// flex may automatically assign the name even if  --outfile is named in the flex command.

int main(int argc, char** argv)
{
  return run(argc, argv);
}

file: src/test-02.l
purpose: source file
Code:
/* scanner for a Pascal-like language

This example is from the flex man pages.

WARNING: see explanation re. main() in test-02.c

*/

/* C Declarations Section */
%{
/* need this for the call to atof() below */
#include <math.h>
%}

/* Lex macro definitions and directives */

DIGIT    [0-9]
ID       [a-z][a-z0-9]*


%%

 /* the rules section */

{DIGIT}+    {
            printf( "An integer: %s (%d)\n", yytext,
                    atoi( yytext ) );
            }


{DIGIT}+"."{DIGIT}*        {
            printf( "A float: %s (%g)\n", yytext,
                    atof( yytext ) );
            }


if|then|begin|end|procedure|function        {
            printf( "A keyword: %s\n", yytext );
            }


{ID}        printf( "An identifier: %s\n", yytext );


"+"|"-"|"*"|"/"   printf( "An operator: %s\n", yytext );


"{"[\^{}}\n]*"}"     /* eat up one-line comments */


[ \t\n]+          /* eat up whitespace */


.           printf( "Unrecognized character: %s\n", yytext );

file: src/test-03.c
purpose: flex output file loader
Code:
#include "test-02.yyc"

#include <stdio.h>
#include <errno.h>
int file_num;
int file_num_max;
char **files;
extern int errno;

int yywrap() {
  fclose(yyin);
  if ( ++file_num < file_num_max ) 
  {
    if ( (yyin = fopen(files[file_num],"r")) == 0 ) 
    {
      perror(files[file_num]);
      exit(1);
    }
    return 0; // continue
  } 
  return 1; // done
}

// main.c -- skeleton created by new.main

int usage(int errcode)
{
  const char* usage_str =
  "\n"
  "This is a program which reads a file and extracts any hyper-text references, and \n"
  "writes them to the standard output.\n"
  ;
  printf("%s", usage_str);
  return errcode;
}

int main(int argc, char *argv[]) {
  if(argc == 1)
    return usage(0);
  
  file_num=1;
  file_num_max = argc;
  files = argv;
  if ( argc > 1 ) {
    if ( (yyin = fopen(argv[file_num],"r")) == 0 ) {
      perror(argv[file_num]);
      exit(1);
    }
  }
  while( yylex() )
          ;
  return 0;
}

file: src/test-03.l
purpose: source file
Code:
/* url ripper to display urls in an html document */

%%
(ftp|http):\/\/[^ \n<>"]*       printf("%s\n",yytext);
.|\n                    ;
Posted in Uncategorized
Views 469 Comments 0
« Prev     Main     Next »
Total Comments 0

Comments

 

  



All times are GMT -5. The time now is 09:03 AM.

Main Menu
Advertisement

My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration