Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions monticore-grammar/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def grammarDependencies = ext {
Completeness = []
MCStatementsBasis = []
Antlr = []
ISOTemporals4Parsing = []

// one dependency
MCSynchronizedStatements = ["MCCommonStatements"]
Expand Down Expand Up @@ -200,6 +201,10 @@ def grammarDependencies = ext {
RegularExpressions = ["MCCommonLiterals"]
SIUnits = ["MCCommonLiterals"]
TupleExpressions = ["ExpressionsBasis"]
TemporalBasis = ["MCCommonLiterals"]
ISOTemporals = ["TemporalBasis"]
EscapedTemporalLiterals = ["TemporalBasis"]
DETemporals = ["TemporalBasis"]

// two dependencies
Cardinality = ["MCBasics", "MCCommonLiterals"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package de.monticore.temporal;
Comment thread
SchmidtMarc marked this conversation as resolved.

/* Alpha-version: This is intended to become a MontiCore stable grammar. */

/**
* This grammar realizes the core interfaces defined in TemporalBasis with the DIN date/time standard.
*
* These date/time-formats are commonly used in German speaking regions.
*/
component grammar DETemporals extends de.monticore.temporal.TemporalBasis {

interface DEInstant extends Instant;

interface DEDate extends Date, DEInstant;

DENumericDate implements DEDate =
((daySource:Digits ".")? monthSource:Digits ".")? yearSource:Digits;

DEAlphanumericDate implements DEDate, Literal =
(daySource:Digits ".")? monthSource:DEMonth yearSource:Digits;

DETime implements Time, DEInstant, Literal =
hourSource:Digits (":" minuteSource:Digits)? (":" secondSource:Digits)? "Uhr";

nokeyword "Uhr";

DEDateTime implements DateTime, DEInstant, Literal =
date:DEDate time:DETime;

/**
* Defines the German months in their full and abbreviated variant.
*/
DEMonth =
month:[ january:"Januar" | january:"Jan."
| february:"Februar" | february:"Feb."
| march:"März" | march:"Mär."
| april:"April" | april:"Apr."
| may:"Mai" | may:"Mai."
| june:"Juni" | june:"Jun."
| july:"Juli" | july:"Jul."
| august:"August" | august:"Aug."
| september:"September" | september:"Sep."
| october:"Oktober" | october:"Okt."
| november:"November" | november:"Nov."
| december:"Dezember" | december:"Dez." ];

nokeyword "Januar", "Februar",
"April", "Mai", "Juni", "Juli",
"August", "September", "Oktober",
"November", "Dezember";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.monticore.temporal;

/* Alpha-version: This is intended to become a MontiCore stable grammar. */

/**
* This grammar makes arbitrary temporal values usable in expressions by defining an escaping rule.
*
* In short, any temporal value t can be turned into an EscapedTemporalLiteral by writing d"t".
*/
component grammar EscapedTemporalLiterals extends de.monticore.temporal.TemporalBasis {

/**
* The only production of EscapedTemporalLiterals, making it possible to use any Instant or Period
* as a Literal (and thus within a Expression via LiteralExpression).
*
* Normally, we would split this production into multiple ones to avoid the explicit optional.
* However, that would cause ambiguity during the parse.
*/
EscapedTemporalLiteral implements Literal = "d\"" (Instant | Period) "\"";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package de.monticore.temporal;

/* Alpha-version: This is intended to become a MontiCore stable grammar. */

/**
* This grammar realizes the core interfaces defined in TemporalBasis with the ISO 8601-1 standard.
*
* These date/time-formats are suitable for use in international communication.
*/
component grammar ISOTemporals extends de.monticore.temporal.TemporalBasis {

interface ISOInstant extends Instant <110>;

/* ======================================================================== */
/* ================================= Date ================================= */
/* ======================================================================== */

interface ISODate extends ISOInstant, Date;

CalendarDate implements ISODate = { !isOrdinalDate() }? Sign? pre:Digits ("-" mid:Digits)? ("-" post:Digits)?;

astrule CalendarDate =
century: java.util.Optional<Integer>
decade: java.util.Optional<Integer>
year: java.util.Optional<Integer>
month: java.util.Optional<Integer>
day: java.util.Optional<Integer>;

OrdinalDate implements ISODate = { isOrdinalDate() }? Sign? pre:Digits ("-" post:Digits)?;

astrule OrdinalDate =
year: int
dayOfYear: int;

interface WeekDate extends ISODate;

BasicWeekDate implements WeekDate, Literal = source:BasicWeekDateToken;

ExtendedWeekDate implements WeekDate = Sign? yearSource:Digits "-" weekSource:WDigits ("-" dayOfWeekSource:Digits)?;

astrule BasicWeekDate =
year: int
week: int
dayOfWeekInternal: java.util.Optional<Integer>;

// A 'W' followed by any number of digits ('0'-'9'). Only used above for the WeekDate rule
// to work around the fact such strings are tokenized as Names.
WDigits = { cmpTokenRegEx(1, "W\\d+") }? source:Name;

enum Sign = plus:"+" | minus:"-";

/* ======================================================================== */
/* ================================= Time ================================= */
/* ======================================================================== */

ISOTime implements ISOInstant, Time =
// Basic format
(preWithT:TDigits Fraction? timeShiftSource:TimeShift?)
// Extended format
| ((pre:Digits | preWithT:TDigits) ":" mid:Digits (":" post:Digits)?
Fraction? timeShiftSource:TimeShift?);

astrule ISOTime =
hour: int
minute: java.util.Optional<Integer>
second: java.util.Optional<Integer>
decimalDigits: java.util.Optional<String>
timeShift: java.util.Optional<Integer>;

// A 'T' followed by any number of digits ('0'-'9') and possibly a 'Z' as the last character.
// Only used above, to work around the fact that strings such as "T123001Z" will be tokenized
// as a single Name token.
TDigits = { cmpTokenRegEx(1, "T\\d+Z?") }? source:Name;

Fraction = (period:"." | comma:",") Digits;

TimeShift = "Z" | Sign pre:Digits (":" post:Digits)?;

/* ======================================================================== */
/* =============================== DateTime =============================== */
/* ======================================================================== */

ISODateTime implements ISOInstant, Literal, DateTime = source:ISODateTimeToken;

astrule ISODateTime =
date: ISODate
time: ISOTime;

/* ======================================================================== */
/* ================================ Period ================================ */
/* ======================================================================== */

interface ISOPeriod extends Period;

FullPeriod implements ISOPeriod = pre:PeriodBegin (Fraction post:PeriodEnd)?;

PeriodBegin = { cmpTokenRegEx(1, "P(\\d+Y)?(\\d+M)?(\\d+D)?T?(\\d+[hH])?(\\d+[mM])?(\\d+[sS])?\\d*") }? source:Name;

PeriodEnd = { cmpTokenRegEx(1, "[hHmMsS]") }? source:Name;

astrule FullPeriod =
years: java.util.Optional<Integer>
months: java.util.Optional<Integer>
days: java.util.Optional<Integer>
hours: java.util.Optional<Integer>
minutes: java.util.Optional<Integer>
seconds: java.util.Optional<Integer>
decimalDigits: java.util.Optional<String>;

WeekPeriod implements ISOPeriod = { cmpTokenRegEx(1, "P[0-9]+W") }? source:Name;

astrule WeekPeriod =
weeks: int;

/* ======================================================================== */
/* ================================ Tokens ================================ */
/* ======================================================================== */

fragment token SignToken = '+' | '-';

fragment token BasicTime = 'T' Digits;

fragment token ExtendedTime = 'T'? Digits ':' Digits (':' Digits)?;

fragment token FractionToken = ('.' | ',') Digits;

fragment token TimeShiftToken = 'Z' | SignToken Digits (':' Digits)?;

fragment token ISOTimeToken = (BasicTime | ExtendedTime) FractionToken? TimeShiftToken?;

token BasicWeekDateToken = SignToken? Digits 'W' Digits;

token ISODateTimeToken = SignToken? Digits '-'? 'W'? Digits ('-' Digits)? ISOTimeToken;

concept antlr {
parserjava {
public boolean isOrdinalDate() {
int extraDigits = 0;
int tokenIndex = 1;
if (cmpToken(tokenIndex, "+", "-")) {
tokenIndex++;
extraDigits = 2;
}

return getToken(tokenIndex).length() == 7 + extraDigits
|| (cmpToken(tokenIndex + 1, "-") && getToken(tokenIndex + 2).length() == 3);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package de.monticore.temporal;

/* Alpha-version: This is intended to become a MontiCore stable grammar. */

/**
* This grammar defines the core interfaces for temporal values.
*
* These interfaces are realized by conservative extensions of this grammar, each covering
* a collection of date/time-formats. Currently these extensions are:
* - ISOTemporals - Covering the ISO-8601 standard, for international use
* - DETemporals - Covering the DIN date/time standard, used in Germany
*
* To enable the use of temporal values as literals there is also the EscapedTemporalLiterals
* extension.
*/
component grammar TemporalBasis extends de.monticore.literals.MCCommonLiterals {

/*========================================================================*/
/*=========================== Core Interfaces ============================*/
/*========================================================================*/

/**
* A point on the time scale. Sub-interfaces differ in their granularity, e.g. the unit of a Date
* is 1 day, while the unit of Time is 1 second.
*/
interface Instant;

/**
* An Instant whose time components can range from centuries to days.
*/
interface Date extends Instant;

/**
* An Instant whose time components can range from hours to fractions of a second.
*/
interface Time extends Instant;

/**
* An Instant which can range over all time components.
*/
interface DateTime extends Instant;

/**
* A length of time.
*/
interface Period;

}
Loading
Loading