Universität Paderborn - Home Universität Paderborn
Die Universität der Informationsgesellschaft

Generating Software from Specifications WS 2013/14 - File TryScanSol.fw

@=~
~p maximum_input_line_length = infinity

The concrete grammar specifies a sequence of Elements
separated by commas. The elements are named terminals.
A production for the terminal Day has been added.
~O~<TryScan.con~>~{
Specification:	Sequence.
Sequence:	Sequence ',' Element / Element.
Element:	Ident / Number.
Element:	Day.
~}

Two tokens are specified here.
Replace them by your favorite token notations and
test the generated scanner and parser:
A definition for the token Day has been added.
It has to occur before the definition of Ident,
because their languages overlap.
Two kinds of comments have been additionally specified.
The Tokens Number and Ident are defined by canned descriptions.
~O~<TryScan.gla~>~{
Number: C_INTEGER
Day:    $Mon|Tue|Wed|Thu|Fri|Sat|Sun [mkDay]
Ident:  PASCAL_IDENTIFIER
        C_COMMENT
        $\/\/ (auxEOL)
~}

Here is a correct input file:
~O~<in.ok~>~{~-
abc, de1, a, a, 
0, 123, 4567,
Mon, Tue, Sun,
0xFF
/* comment */
// line comment
~}

Here is an erroneous input file:
~O~<in.err~>~{~-
1a
?,
Mit,
thu,
0xxF
/*
~}

The following rules of the abstract syntax are used in Exercise 6c
to output token encodings.
~O~<TokenSpecs.lido~>~{
RULE p1: Element ::= Ident COMPUTE
  printf ("p1: token code %d in line %d\n", Ident, LINE);
  printf ("p1: identifier %s in line %d\n", StringTable(Ident), LINE);
END;

RULE p2: Element ::= Number COMPUTE
  printf ("p2: token code %d in line %d\n", Number, LINE);
END;

RULE p3: Element ::= Day COMPUTE
  printf ("p3: token code %d in line %d\n", Day, LINE);
END;
~}

The following three macros implement a little C module.
It defines functions to be called as a token encoding functions.
In the present state myToken only prints some information on every
accepted token:
~O~<TryScan.HEAD.phi~>~{
#include "csm.h"
#include "TryScan.h"
~}
~O~<TryScan.h~>~{
extern void myToken (char *start, int length, int *class, int *intrinsic);
extern void mkDay (char *start, int length, int *class, int *intrinsic);
~}
~O~<TryScan.c~>~{
#include <stdio.h>
#include "TryScan.h"

int count = 0;

void myToken (char *start, int length, int *class, int *intrinsic)
{
  *intrinsic=++count;
  printf ("token %d first char >%c<\n", count, *start);
}

void mkDay (char *d, int l, int *c, int *i)
{
    switch (d[0]) {
        case 'F': *i = 5; break;
        case 'M': *i = 1; break;
        case 'W': *i = 3; break;
        case 'S': *i = (d[1] == 'a'? 6 : 7); break;
        case 'T': *i = (d[1] == 'u' ? 2 : 4); break;
    }
}
~}

Generiert mit Camelot | Probleme mit Camelot? | Geändert am: 06.11.2013