Menu

[114822]: / cola / frontend / analyze.fw  Maximize  Restore  History

Download this file

200 lines (155 with data), 5.3 kB

@! analyze.fw  -- first edit Mon Dec 19 1994        -- by Karl Prott
@p typesetter = tex
@p maximum_input_line_length = infinity

\documentstyle[11pt,a4]{article}
\setlength{\textwidth}{16.5cm}
\setlength{\textheight}{25cm}
\setlength{\parindent}{0mm}
\setlength{\parskip}{6pt}

\setlength{\voffset}{-1in}
\setlength{\hoffset}{-0.5in}
% Defaults for offset
% \setlength{\voffset}{0pt}
% \setlength{\hoffset}{0pt}


\begin{document}


\section{Semantic analysis}

This part implements the consistent renaming task and the
classification into terminals and nonterminals.

\begin{description}
{\tt
\item[depends on:] {\it nothing\/}

\item[exports:]
  \begin{tabular}{l | l}
    Attribute & For Symbols \\\hline
    Key, Sym & connection, literal, grammarname, rulename,
    nonterminal,\\
    & nonliteral, terminal, t\_or\_nt, modification\\
    type & terminal, nonterminal, t\_or\_nt \\
  \end{tabular}
}
\end{description}



\subsection{Consistent Renaming}

Two name spaces are defined. One name space is used for literal
symbols and the other for nonliteral symbols. This is necessary to
distinguish {\tt A} from {\tt 'A'}, because literal symbols are stored
without delimiters. The symbols {\tt literal, connection} represent a
literal symbol and the symbols {\tt grammarname, rulename,
  nonterminal, nonliteral} represent nonliteral symbols. {\tt
  terminal, t\_or\_nt, modification} may be both.

@O@<rename.specs@>@{
$/Name/AlgScope.gnrc +instance=Literal     :inst
$/Name/AlgScope.gnrc +instance=Nonliteral  :inst
@}

@O@<rename.lido@>@{
ATTR    Sym:    int;
ATTR    Key:    DefTableKey;

SYMBOL  LiteralIdDefScope        COMPUTE
    SYNT.Sym = TERM;
END;

SYMBOL  NonliteralIdDefScope     COMPUTE
    SYNT.Sym = TERM;
END;

SYMBOL root INHERITS LiteralRootScope, NonliteralRootScope END;

SYMBOL  connection      INHERITS LiteralIdDefScope END;
SYMBOL  literal         INHERITS LiteralIdDefScope END;
SYMBOL  grammarname     INHERITS NonliteralIdDefScope END;
SYMBOL  rulename        INHERITS NonliteralIdDefScope END;
SYMBOL  nonterminal     INHERITS NonliteralIdDefScope END;
SYMBOL  nonliteral      INHERITS NonliteralIdDefScope END;

SYMBOL  lit_or_nonlit COMPUTE
    SYNT.Key = CONSTITUENT (literal.Key, nonliteral.Key);
    SYNT.Sym = CONSTITUENT (literal.Sym, nonliteral.Sym);
END;

SYMBOL  terminal        INHERITS lit_or_nonlit END;
SYMBOL  t_or_nt         INHERITS lit_or_nonlit END;
SYMBOL  modification    INHERITS lit_or_nonlit END;
@}



\subsection{Classifying in Terminals and Nonterminals}

For symbol {\tt t\_or\_nt} it is necessary to decide whether it
represents a terminal or a nonterminal. If a symbol is classified as
terminal and nonterminal an error message is printed. Property {\tt
  Class} implements the result of the classification.


@O@<classify.head@>@{
#include "classify.h"
#include "err.h"
@}

@O@<classify.pdl@>@{
Class: int;
@}

@O@<classify.lido@>@{
/**** Classifying in terminals and nonterminals ****/
/***************************************************/

ATTR    type:   int;
ATTR    Class, GotAllClass:     VOID;

SYMBOL  root    COMPUTE
  SYNT.GotAllClass = CONSTITUENTS(nonterminal.Class, terminal.Class);
END;

SYMBOL  terminal        COMPUTE
    SYNT.type = Kp_term;
    SYNT.Class = Classify(THIS.Key, TERMINAL);
    IF( EQ(GetClass(THIS.Key, FAULT), FAULT),
        message(ERROR, MESSAGE1, 0, COORDREF)
      )         DEPENDS_ON INCLUDING root.GotAllClass;
END;

SYMBOL  nonterminal     COMPUTE
    SYNT.type = Kp_nterm;
    SYNT.Class = Classify(THIS.Key, NONTERMINAL);
    IF( EQ(GetClass(THIS.Key, FAULT), FAULT),
        message(ERROR, MESSAGE2, 0, COORDREF)
      )         DEPENDS_ON INCLUDING root.GotAllClass;
END;

SYMBOL  t_or_nt COMPUTE
    SYNT.Class = IF( EQ(GetClass(THIS.Key, UNDEF), UNDEF),
                     ResetClass(THIS.Key, TERMINAL)
                   )            DEPENDS_ON INCLUDING root.GotAllClass;
    SYNT.type =
	IF( EQ(GetClass(THIS.Key, UNDEF), NONTERMINAL), Kp_nterm, Kp_term)
		DEPENDS_ON THIS.Class;
END;
@}

@O@<classify.h@>@{
#ifndef CLASSIFY_H
#define CLASSIFY_H

#include "deftbl.h"             /* for DefTableKey */

#define FAULT           (-1)
#define UNDEF           0
#define TERMINAL        1
#define NONTERMINAL     2

#define MESSAGE1 "Terminal expected: symbol has been used as nonterminal too"
#define MESSAGE2 "Nonterminal expected: symbol has been used as terminal too"

extern  void
#if defined(__STDC__) || defined(__cplusplus)
        Classify(DefTableKey key, int class);
#else
        Classify();
#endif


#endif
@}

@O@<classify.c@>@{
#include "classify.h"
#include "pdl_gen.h"

void
#if defined(__STDC__) || defined(__cplusplus)
        Classify(DefTableKey key, int class)
#else
        Classify(key, class)
        int     class;
        DefTableKey key;
#endif
{
   switch ( GetClass(key, UNDEF) )
   {
        case FAULT      : break;
        case UNDEF      : ResetClass(key, class);
                          break;
        case TERMINAL   : if ( class == NONTERMINAL )
                                ResetClass(key, FAULT);
                          break;
        case NONTERMINAL: if ( class == TERMINAL )
                                ResetClass(key, FAULT);
                          break;
   } /* of switch */
   return;
} /* of Classify() */
@}

\end{document}
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.