Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
124 changes: 119 additions & 5 deletions gen/oap/application/plugin/gen/parser/OapParser.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 37 additions & 1 deletion gen/oap/application/plugin/gen/parser/_OapLexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,27 @@ private char peekChar() {
return zzMarkedPos < zzEndRead ? zzBuffer.charAt(zzMarkedPos) : '\0';
}

// Looks ahead from the current position (right after a dash-list '-') to decide whether this
// item is itself a bare flat map (YAML-style "- key: value" with more "key: value" pairs on
// following lines at the same indent, no wrapping '{'/':') rather than a plain scalar/ref/
// array/braced-object value. True iff a KEY_NAME-shaped run of characters is immediately
// (modulo spaces/tabs) followed by ':' - the trailing content after that ':' is irrelevant
// since a value follows on the same line (e.g. "class: oap.ws.account.User").
private boolean dashItemStartsKeyValue() {
int i = zzMarkedPos;
while (i < zzEndRead && (zzBuffer.charAt(i) == ' ' || zzBuffer.charAt(i) == '\t')) i++;
int start = i;
if (i >= zzEndRead || !Character.isJavaIdentifierStart(zzBuffer.charAt(i))) return false;
while (i < zzEndRead) {
char c = zzBuffer.charAt(i);
if (Character.isJavaIdentifierPart(c) || c == '-' || c == '/') { i++; continue; }
break;
}
if (i == start) return false;
while (i < zzEndRead && (zzBuffer.charAt(i) == ' ' || zzBuffer.charAt(i) == '\t')) i++;
return i < zzEndRead && zzBuffer.charAt(i) == ':';
}

// Scans forward from the current position, skipping spaces/tabs, to decide what a nested
// key's ':' means: true if only whitespace/comment/EOF follows before the next newline (this
// ':' opens a nested block, YAML-style), false if real content follows on the same line
Expand Down Expand Up @@ -1364,6 +1385,15 @@ else if (zzAtEOF) {
if (!indentStack.isEmpty()) {
indentStack.pop();
zzAtEOF = false;
// Same "not progressing" hazard BOL_CHECK/BOL_CHECK2 ping-pong around: draining 2+
// still-open indent levels at real EOF emits that many zero-width OAP_DEDENT tokens in a
// row, all at the same offset - and unlike BOL_CHECK's dedent branch, this rule never
// called yybegin(), so consecutive calls also kept the exact same (tokenType, start, end,
// state) tuple, which ValidatingLexerWrapper (used by OapHighlightingLexer for editor/diff
// highlighting) flags as an infinite loop. Alternate state here too, purely so the tuple
// differs between successive EOF-triggered dedents; BOL_CHECK/BOL_CHECK2 aren't otherwise
// reachable once real input is exhausted, so reusing them here is safe.
yybegin(yystate() == BOL_CHECK ? BOL_CHECK2 : BOL_CHECK);
return OAP_DEDENT;
}
return null;
Expand Down Expand Up @@ -1714,7 +1744,13 @@ else if (zzAtEOF) {
// fall through
case 160: break;
case 55:
{ yypushState(_OBJECT_ENTITY); return OAP_DASH;
{ if (dashItemStartsKeyValue()) {
yypushState(_OBJECT);
indentStack.push(-1);
} else {
yypushState(_OBJECT_ENTITY);
}
return OAP_DASH;
}
// fall through
case 161: break;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ org.gradle.caching = true

org.gradle.jvmargs=-XX\:MaxHeapSize\=4256m -Xmx4256m -Xms2000m

version = 0.0.12
version = 0.0.13
47 changes: 45 additions & 2 deletions grammars/_OapLexer.flex
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,27 @@ import static oap.application.plugin.gen.OapTypes.*;
return zzMarkedPos < zzEndRead ? zzBuffer.charAt(zzMarkedPos) : '\0';
}

// Looks ahead from the current position (right after a dash-list '-') to decide whether this
// item is itself a bare flat map (YAML-style "- key: value" with more "key: value" pairs on
// following lines at the same indent, no wrapping '{'/':') rather than a plain scalar/ref/
// array/braced-object value. True iff a KEY_NAME-shaped run of characters is immediately
// (modulo spaces/tabs) followed by ':' - the trailing content after that ':' is irrelevant
// since a value follows on the same line (e.g. "class: oap.ws.account.User").
private boolean dashItemStartsKeyValue() {
int i = zzMarkedPos;
while (i < zzEndRead && (zzBuffer.charAt(i) == ' ' || zzBuffer.charAt(i) == '\t')) i++;
int start = i;
if (i >= zzEndRead || !Character.isJavaIdentifierStart(zzBuffer.charAt(i))) return false;
while (i < zzEndRead) {
char c = zzBuffer.charAt(i);
if (Character.isJavaIdentifierPart(c) || c == '-' || c == '/') { i++; continue; }
break;
}
if (i == start) return false;
while (i < zzEndRead && (zzBuffer.charAt(i) == ' ' || zzBuffer.charAt(i) == '\t')) i++;
return i < zzEndRead && zzBuffer.charAt(i) == ':';
}

// Scans forward from the current position, skipping spaces/tabs, to decide what a nested
// key's ':' means: true if only whitespace/comment/EOF follows before the next newline (this
// ':' opens a nested block, YAML-style), false if real content follows on the same line
Expand Down Expand Up @@ -719,9 +740,22 @@ KEY_NAME=[:jletter:] ([:jletterdigit:]|[-/])*
// case: BOL_CHECK redirects here instead of _OBJECT once it sees the first real character
// of the block is '-', which a nested-object key can never start with). Reuses
// _OBJECT_ENTITY's existing value matching (<ref>, [array], {object}, bool, id_value,
// function, string) for whatever follows each dash.
// function, string) for whatever follows each dash. When the dash is instead followed by a
// "key: value" pair (dashItemStartsKeyValue()), the item is a bare flat map spanning possibly
// several lines (e.g. "- class: X\n field: Y") - push _OBJECT directly (not _OBJECT_ENTITY)
// with an unresolved indent context so BOL_CHECK captures the column of the first continuation
// key ("field") the same way any other colon-opened block does, and a later dedent back to this
// item's own dash column pops back out to _ARRAY_BLOCK_ITEM for the next '-'.
<_ARRAY_BLOCK_ITEM> {
"-" { yypushState(_OBJECT_ENTITY); return OAP_DASH; }
"-" {
if (dashItemStartsKeyValue()) {
yypushState(_OBJECT);
indentStack.push(-1);
} else {
yypushState(_OBJECT_ENTITY);
}
return OAP_DASH;
}

{WHITE_SPACE} { return WHITE_SPACE; }
{NEXTLINE} { return handleNextline(); }
Expand Down Expand Up @@ -816,6 +850,15 @@ KEY_NAME=[:jletter:] ([:jletterdigit:]|[-/])*
if (!indentStack.isEmpty()) {
indentStack.pop();
zzAtEOF = false;
// Same "not progressing" hazard BOL_CHECK/BOL_CHECK2 ping-pong around: draining 2+
// still-open indent levels at real EOF emits that many zero-width OAP_DEDENT tokens in a
// row, all at the same offset - and unlike BOL_CHECK's dedent branch, this rule never
// called yybegin(), so consecutive calls also kept the exact same (tokenType, start, end,
// state) tuple, which ValidatingLexerWrapper (used by OapHighlightingLexer for editor/diff
// highlighting) flags as an infinite loop. Alternate state here too, purely so the tuple
// differs between successive EOF-triggered dedents; BOL_CHECK/BOL_CHECK2 aren't otherwise
// reachable once real input is exhausted, so reusing them here is safe.
yybegin(yystate() == BOL_CHECK ? BOL_CHECK2 : BOL_CHECK);
return OAP_DEDENT;
}
return null;
Expand Down
Loading
Loading