Class RawParser<D>

java.lang.Object
eu.bandm.tscore.base.RawParser<D>
Type Parameters:
D - type of the document identifier coming from the lexer.

public class RawParser<D> extends Object
Recursive-descent parser for the raw level of tscore. Consumes tokens from a lexer. Generates a TimeScape object. Roughly the accepted syntax can be described by the following mere symbolic rules (for details see the user documentation):
  timeScape    ::= conform? timeless* voxParams* part* EOF
  conform      ::= "CONFORM" qident    FIXME CONFORM RAUS   USE "conforma = eu.bandm.music.applications.X" instead !
  qident       ::= ident ("." ident)*

  timeless     ::= ident "="  qident_or_stringconst  FIXME ANDERS

  voxParams    ::= VOX_and_name conform?, timeless*
  VOX_and_name ::= "VOX"  ident_or_stringconst
  part         ::= "PARS"  ident_or_stringconst conform? timeless* 
                             voxParams* accolade*
  accolade     ::= "T" timeline NL vox*
  vox          ::= VOX_and_name NL (paramIdent token* NL)

  --- a maximal score can thus look like: ---

  CONFORM xxxx
      a=xxx b=xxx
    VOX A CONFORM xxxx a=xxx b=xxx
    PARS A CONFORM xxx  a=xxx b=xxx
      VOX A CONFORM xxxx a=xxx b=xxx
      T      1   2   3
      VOX A  x   x x x

  
The implementation is as recursive decent parser, LL(1), explicity inquiring the type of the next Token. This is delivered by a Lexer.

This parser only collects text fragments and assigns them to top time points, timeless parameter settings and parameters of events, which are related to timepoints and voices. No kind of semantical evaluation happens here, but by subsequent interpretation steps.

  • Field Details

  • Constructor Details

    • RawParser

      public RawParser()
  • Method Details

    • parse

      Top-level parser for
      timeScape ::= timeless* voxParams* part* EOF. Returns a time scape, which is a collection of some meta data (Timeless) for the whole score and for voices), followed by the "parts", which hold the real timepoints and events, for each part independently, plus possibly more meta data. The meta data from the score level may later be distributed by the particular evaluation code, or ignored, or even explicitly rejected.

      The parser is implemented as an explicit recursive-descent parser.

    • getDocumentId

      @Opt protected <D> D getDocumentId(Token<D,Lexer.TokenType> token)
      Extract the document id from the given token, which is delivered by the tscore lexer TScoreLexer.
    • locError

      protected void locError(String m, Object... args)
      Generates an error message with given text and arguments, referring to the next location.
    • locWarning

      protected void locWarning(String m, Object... args)
      Generates a warning message with given text and arguments, referring to the next location.
    • react

      protected void react(Modifiers.Reaction react, String txt, Object... args)
      Generates possibly a message with the given text and arguments, referring to the next location, either as error or as warning, depending on "react". This allows to choose between "silently allow", "warning", and "error".
    • react

      protected void react(Modifiers.Reaction react, Location<XMLDocumentIdentifier> loc, String txt)
      Generates possibly a message with the given text and arguments, referring to the explicitly given location, either as error or as warning, depending on "react". This allows to choose between "silently allow", "warning", and "error".
    • react

      protected void react(Modifiers.Reaction react, Location<XMLDocumentIdentifier> loc, String txt, Object... args)
      Generates possibly a message with the given text, arguments and location, either as error or as warning, depending on "react". This allows to choose between "silently allow", "warning", and "error".
    • isReserved

      boolean isReserved(String token)
      Whether the token text is a reserved word. Currently these are "PARS", "CONFORM", "VOX, "T".
    • consume

      protected void consume()
      Fill local variable nextToken by pulling from tokenStream.
    • LA

      protected boolean LA(Lexer.TokenType t)
      Tests whether type of nextToken is the given. Type constants are in Lexer.TokenType.
    • LA_ident

      protected boolean LA_ident(String s)
      Tests whether the reserved word given is in nextToken.
    • ws_or_nl_or_comment

      protected boolean ws_or_nl_or_comment()
      Parse (=test, consume and return) whitespace, including newline.
    • ident_or_stringConst

      @Opt protected @Opt String ident_or_stringConst()
      Parse (=test, consume and return) TokenType.CHARSTRING or TokenType.IDENT. Strips quote signs.
    • qident

      @Opt protected @Opt String qident()
      Parse (=test, consume and return) dotted-separated list of idents. Return null iff none could be parsed (then parser state stays unaltered)
    • conform

      @Opt protected @Opt String conform()
      Parser function (=test, consume and return) for
      "conform ::= CONFORM qident"
      Returns:
      whether this syntax rule has been parsed.
    • timelessSequence

      protected void timelessSequence(List<Timeless> target)
      Parser code (=test, consume, and store to target) for a sequene of timeless values, which can be assigments or simple flags. Parsing is stopped by the reserved words »VOX«, »PARS«, and »T"«. This method constructs Timeless model elements and enters them into »target«. The utilities for interpreting those as data of different types are in Timelesses.

      Timeless values can appear at top level (container is the growing TimeScape, or on two lower levels PARS and VOX with those objects as containers.

          a = b  c = d  e  f = g = (h i) 
            VOX c
             a = b
            VOX d
             a = b
          PARS a
             a = b
          PARS b
          a = b
             VOX c
             a = b
             T        17      18
             VOX c    x   x   x
         

      Input grammar is (symbollically) as follows:

         timelessSequence ::= timelessLine *
         timelessLine     ::= timelessSingleValue ( "=" timelessLine)?
                           |  "(" timelessSequence ")"
         timelessSingleValue ::= (ident | charstring | "/" | "!" | "*" | ...)+
         

      timelessSingleValue does not allow intervening whitespace or comments, the other rules do.
      "VOX" "PARS" and "T" stop accepting.

      The semantic role of lists in »(...)« can vary: sets, lists, bags, or records.

      Parameters:
      target - where to store the parsed and constructed data.
    • timelessLine

      protected Timeless timelessLine()
      Parses one single value or assignment. This can be utmost simple like »a}«, but also arbitrary comples as in »a = b = (c=d e=f 1 2 3)«. Constructs and returns a data object. Parsing is stopped by the reserved words »VOX«, »PARS«, and »T"«, and when a top-level closing parentheses has been consumed.
    • timelessSingleValue

      @Opt protected @Opt String timelessSingleValue()
      Accept all tokens which are not whitespace or parantheses or comments and concatenate their text contents. Quoted strings are stripped off the doublequote signs.
      FIXME CHECK AND DOCU: »"+-"3 = value« ist möglich !?!?!?
      »"" = value« ist möglich !?!?!?
      Returns:
      null if no text value could be collected, but an empty string if an empty string constant appears in the input.
    • voxParams

      protected boolean voxParams(Container container)
      Parser function (=test, consume and return) for
      voxParams ::= VOX_and_name conform?, timeless* Creates a new voice by calling VOX_and_name(Container,boolean), which stores this either to the timescape or to the part under construction. Each voice name may only appear once in these declarations.
      Returns:
      whether this syntax rule has been parsed.
    • part

      protected boolean part(TimeScape current_ts)
      Parser function (=test, consume and return) for
      pars ::= PARS ident_or_stringconst conform timeless* voiceparams accolade*
      Parameters:
      current_ts - where to store the constructed PARS data
      Returns:
      whether this syntax rule has been parsed.
    • accolade

      protected boolean accolade(Part current_part)
      Parser function (=test, consume and return) for
      accolade ::= T timeline NL vox* This is the central parsing function which creates timepoints, events, voices and registers all these with the part under construction.

      Top timepoints may use more than one (>1) source line, iff allowed by modifiers. The possible characters for sub-divisions are given as string constants in modifiers. Each source fragment not contained therein is assumed a top-level timepoint source and stored for later parsing in Part.tlines.

      This method enters resulting the timeline map into the "current_part" argument, intp its field ".tlines", and event data in the voice objects, entered also in "current_part".

      Returns:
      whether this syntax rule has accepted anything.
    • makeLowerTps

      protected void makeLowerTps(SortedMap<Integer,Tp> col2tp, String sign, Map<Integer,String> sources, RawParser<D>.TokenMap unpacked)
      Step through T-line source fragments and create TpSubs which divide the interval between already recognized, higher timepoint levels.
      Parameters:
      col2tp - Input data and output target where to store the new column definitions.
      sign - the single string which (as only!) stands for division points of this level.
      sources - the source fragment sequence, packed into one(1) string for each position=column.
      unpacked - the original source token sequence, only needed to get location information for messages
    • VOX_and_name

      @Opt protected @Opt Vox VOX_and_name(Container container, boolean multiple)
      Parse function (=test, consume and return) for
      VOX_and_name ::= VOX ident
      Can be called (a) in context of meta values (in a score or in a part, before the first T-line) or (b) in an accolade after the T-line. In (a) the voice is only carrier of timeless attributes, which later can be (possibly) distributed to voices with the same name in accolades. No voice name may be repeated.

      In (b) it is contained in a part and may be repeated, but not in the same accolade = under the same T-line.

      If the Vox object dos not yet exists: create it and store it to score or part.

      Returns:
      the new Vox object, or null if this rule has consumed nothing.
    • voice

      boolean voice(Part part, SortedMap<Integer,Tp> col2tp, Set<String> voicesInAccolade)
      Parse function (=test, consume and return) for
      "vox ::= VOX ident token NL (paramIdent token* NL)"
      Is called in the context of parsing an accolade, i.e. events under a T-line. Store resulting vox object to argument "part", and resulting events to the vox object (into several different collections in parallel). Generates new timepoints iff events start on columns not defined by the T-line.
      Returns:
      whether this syntax rule has been parsed.
    • foldInto

      Folds a sequence of input tokens in the main parameter line of a voice into a sub-tree of RawParser<D>.PosList, controlled by opening and closing parentheses. As a first step, this is independent from the timepoints in the time line. Stores also the position of the closing parentheses of the level it is called for, see RawParser<D>.PosList for details.
      Parameters:
      target - the pre-constructed output storage.
      data - the input data which starts at this level
    • isTopTpText

      protected boolean isTopTpText(String t)
      Allow everything as top timepoint which is not contained in the string constants which make up the sub-dividers.
      Attention: adjacent sub-dividers without any separating blank like »!!« will not be recognized as two sub-dividers but as text.
    • collectFragments

      protected RawParser<D>.TokenMap collectFragments(int firstFragmentColumn, boolean breakAtParentheses)
      Parser function (=test, consume and return) for unparsed, raw token sequence in time lines and parameter lines. Collects all contiguous non-white-space fragments ordered by increasing starting column, and (secondarily) by increasing line numbers; returns them in a RawParser<D>.TokenMap, which is a kind of SortedMap.
      New fragment is started with whitespace, newline, etc.
      Double quotes are used to escape whitespace and parentheses break behaviour; quote signs are stripped from result.
      Stops whenever the offside given by firstFragmentColumn is undercut, i.e. when a linke starts left of it.
      Parameters:
      breakAtParentheses - whether parentheses are always a fragment on their own.
      Returns:
      a map from the column numbers to the sequence of all tokens starting there (in line order of the lines considered)