package grammar.java;
import static grammar.GrammarDSL.*;
import compiler.QuotationMacro;
import compiler.Macro;
import grammar.Expression;
import grammar.Expression.Rule;
import grammar.Grammar;
/**
* Grammar rules for macro definitions and quotation.
*
* @see JavaGramar
*/
public class _E_MacroDefinitions extends _D_Requires
{
//============================================================================
// MACRO SYNTACTIC SPECIFICATION
//============================================================================
/*****************************************************************************
* The right square bracket needs to be escaped in characters classes and
* ranges.
*/
public final Expression pegChar = atomic(rule_seq(
seq(not(rSqBra), choice(str("\\]"), charLiteralNoQuotes))
));
/****************************************************************************/
public final Expression pegStar = operator("*", "+");
/****************************************************************************/
public final Expression pegPlus = operator("+", "+/");
/****************************************************************************/
public final Expression charClassParsingExpression = rule_seq(
opt(str("^")), lSqBra, star(not(rSqBra), pegChar), rSqBra);
/****************************************************************************/
public final Expression charRangeParsingExpression = rule_seq(
opt(str("^")),
lSqBra, charLiteralNoQuotes, str("-"), pegChar, rSqBra);
/****************************************************************************/
public final Expression underscorePasingExpression = rule(spaced(str("_")));
/****************************************************************************/
public final Expression literalParsingExpression = rule_seq(
stringLiteral, opt(minus));
/****************************************************************************/
public final Expression referenceParsingExpression = rule(identifier);
/****************************************************************************/
public final Expression parenParsingExpression = rule_seq(
lPar, ref("parsingExpression"), rPar);
/****************************************************************************/
public final Expression primaryParsingExpression = rule(
underscorePasingExpression,
literalParsingExpression,
referenceParsingExpression,
charClassParsingExpression,
charRangeParsingExpression,
parenParsingExpression
);
/****************************************************************************/
public final Expression suffixParsingExpression = rule_seq(
primaryParsingExpression,
opt(choice(pegStar, pegPlus, qMark))
);
/****************************************************************************/
public final Expression starPlus = rule(spaced(str("*+")));
/****************************************************************************/
public final Expression plusSlash = rule(spaced(str("+/")));
/****************************************************************************/
public final Expression notParsingExpression = rule_seq(
bang, suffixParsingExpression);
/****************************************************************************/
public final Expression andParsingExpression = rule_seq(
and, suffixParsingExpression);
/*****************************************************************************
* Slightly tricky because of the need to disallow spaces around the colon.
* Need to simplify.
*/
public final Expression captureExpression = rule(
seq(
not(star(letterOrDigit), fspacing), identifier,
str(":"), ref("prefixParsingExpression")
),
seq(str(":"), referenceParsingExpression)
);
/****************************************************************************/
public final Expression prefixParsingExpression = rule(
andParsingExpression,
notParsingExpression,
captureExpression,
suffixParsingExpression
);
/****************************************************************************/
public final Expression untilParsingExpression = rule_seq(
prefixParsingExpression, starPlus, prefixParsingExpression);
/****************************************************************************/
public final Expression untilOnceParsingExpression = rule_seq(
prefixParsingExpression, plusPlus, prefixParsingExpression);
/****************************************************************************/
public final Expression listParsingExpression = rule_seq(
prefixParsingExpression, plusSlash, prefixParsingExpression);
/****************************************************************************/
public final Expression binaryParsingExpression = rule(
untilParsingExpression,
untilOnceParsingExpression,
listParsingExpression,
prefixParsingExpression
);
/****************************************************************************/
public final Expression sequenceParsingExpression = rule(plus(
binaryParsingExpression));
/****************************************************************************/
public final Expression parsingExpression = rule(list(
pipe, sequenceParsingExpression));
//============================================================================
// QUOTATION SYNTAX
//============================================================================
/****************************************************************************/
public final Expression hash = operator("#");
/****************************************************************************/
public final Expression hashat = operator("#@");
/****************************************************************************/
public final Expression quote = operator("'");
/****************************************************************************/
public final Expression backquote = operator("`");
/*****************************************************************************
* Does not include trailing space.
*/
public final Expression backslash = rule(str("\\"));
/*****************************************************************************
* Upon interpreting the quote syntax, instances of the "insert" rule preceded
* by a backslash have to be filtered out. See {@link compiler.util.Quoter}.
*/
public final Expression regularUnquotation = rule_seq(
opt(backslash), hash,
choice(ref("unquotation"), unaryExpression));
/****************************************************************************/
public final Expression spliceDelimiter = rule(star(choice(
escape,
str("\\|"),
seq(not(str("|")), any)
)));
/****************************************************************************/
public final Expression spliceDelimiters = rule_seq(str("|"),
spliceDelimiter, str("|"),
spliceDelimiter, str("|"),
spliceDelimiter, str("|")
);
/****************************************************************************/
public final Expression splicePrefix = rule_seq(
opt(backslash), hashat, spliceDelimiters, spacing
);
/****************************************************************************/
public final Expression splice = rule_seq(splicePrefix, unaryExpression);
/****************************************************************************/
public final Expression unquotation = rule(regularUnquotation, splice);
/****************************************************************************/
public final Expression qEndMarker = seq(rSqBra, choice(quote, backquote));
/****************************************************************************/
public final Expression escapedQEndMarker = rule_seq(backslash, qEndMarker);
/****************************************************************************/
public final Expression sourceFragmentChar = seq(not(qEndMarker), any);
/****************************************************************************/
public final Expression sourceFragment = rule_seq(
star(until(sourceFragmentChar,
choice(ref("quotation"), unquotation, escapedQEndMarker))),
star(sourceFragmentChar));
/*****************************************************************************
* Note that because lSqBra consumes trailing whitespace, quotation cannot
* be used to quote whitespace.
*/
public final Rule simpleQuotation = rule_seq(
quote, identifier, lSqBra, sourceFragment, rSqBra, quote);
/****************************************************************************/
public final Rule quasiquotation = rule_seq(
backquote, identifier, lSqBra, sourceFragment, rSqBra, backquote);
/****************************************************************************/
public final Rule quotation = rule(simpleQuotation, quasiquotation);
//============================================================================
// DYNAMIC QUOTATION
//============================================================================
/* Quotation syntax that can embedded within a Java string to be able to quote
* in pure java (without the need to preprocess any file). */
//============================================================================
/*****************************************************************************
* @see {@link #unquotation}
*/
public final Expression insertMarker = rule_seq(
choice(splicePrefix, seq(opt(backslash), hash)),
parseIntNumber);
/****************************************************************************/
public final Expression dynamicSourceFragment = rule_seq(
star(until(any, insertMarker)), star(any));
//============================================================================
// MACRO DECLARATION / DEFINITION
//============================================================================
// To be inserted in classMemberDeclaration.
//============================================================================
/****************************************************************************/
public final Expression raw = keyword("raw");
/****************************************************************************/
public final Expression prioritary = keyword("prioritary");
/****************************************************************************/
public final Expression as = keyword("as");
/****************************************************************************/
public final Expression under = keyword("under");
/****************************************************************************/
public final Expression replaces = keyword("replaces");
/****************************************************************************/
public final Expression called = keyword("called");
/****************************************************************************/
public final Expression strategy = rule(choice(as, under, replaces, called));
/****************************************************************************/
public final Rule macroDefinition = rule_seq("macroDefinition",
opt(raw), opt(prioritary), macro, identifier, strategy, opt(identifier),
colon, parsingExpression, choice(block, semi));
//============================================================================
@Override public void initialize(Grammar grammar)
{
super.initialize(grammar);
/* Currently, a macro file can contain type definitions, which will simply
* be ignored. */
grammar.addExistingRuleAlternative(grammar.rule("topLevelTypeDeclaration"),
macroDefinition, false);
Macro quotations = new Macro("quotationm", "unaryExpression",
grammar, quotation, new QuotationMacro(), Macro.Strategy.AS, false, false);
quotations.enable();
macroDefinition.callbacks = new CallbacksMacroDefinition(grammar);
charClassParsingExpression .callbacks = new CharClassCallbacks();
charRangeParsingExpression .callbacks = new CharRangeCallbacks();
underscorePasingExpression .callbacks = new AnyCallbacks();
literalParsingExpression .callbacks = new LiteralCallbacks();
referenceParsingExpression .callbacks = new ReferenceCallbacks();
suffixParsingExpression .callbacks = new SuffixCallbacks();
untilParsingExpression .callbacks = new UntilCallbacks();
untilOnceParsingExpression .callbacks = new UntilOnceCallbacks();
listParsingExpression .callbacks = new ListCallbacks();
notParsingExpression .callbacks = new NotCallbacks();
andParsingExpression .callbacks = new AndCallbacks();
captureExpression .callbacks = new CaptureCallbacks();
sequenceParsingExpression .callbacks = new SequenceCallbacks();
parsingExpression .callbacks = new ChoiceCallbacks();
}
}