diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRLexer.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRLexer.java index b73a67acc..20dfc5418 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRLexer.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRLexer.java @@ -79,10 +79,14 @@ public class FHIRLexer { return currentLocation; } - public boolean isConstant(boolean incDoubleQuotes) { - return current != null && (current.charAt(0) == '\'' || (incDoubleQuotes && current.charAt(0) == '"') || current.charAt(0) == '@' || current.charAt(0) == '%' || + public boolean isConstant() { + return current != null && (current.charAt(0) == '\'' || current.charAt(0) == '"') || current.charAt(0) == '@' || current.charAt(0) == '%' || current.charAt(0) == '-' || current.charAt(0) == '+' || (current.charAt(0) >= '0' && current.charAt(0) <= '9') || - current.equals("true") || current.equals("false") || current.equals("{}")); + current.equals("true") || current.equals("false") || current.equals("{}"); + } + + public boolean isFixedName() { + return current != null && (current.charAt(0) == '`'); } public boolean isStringConstant() { @@ -210,7 +214,7 @@ public class FHIRLexer { if (ch == '}') cursor++; current = source.substring(currentStart, cursor); - } else if (ch == '"'){ + } else if (ch == '"') { cursor++; boolean escape = false; while (cursor < source.length() && (escape || source.charAt(cursor) != '"')) { @@ -241,6 +245,20 @@ public class FHIRLexer { current = source.substring(currentStart, cursor); if (ech == '\'') current = "\'"+current.substring(1, current.length() - 1)+"\'"; + } else if (ch == '`') { + cursor++; + boolean escape = false; + while (cursor < source.length() && (escape || source.charAt(cursor) != '`')) { + if (escape) + escape = false; + else + escape = (source.charAt(cursor) == '\\'); + cursor++; + } + if (cursor == source.length()) + throw error("Unterminated string"); + cursor++; + current = "`"+source.substring(currentStart+1, cursor-1)+"`"; } else if (ch == '@'){ int start = cursor; cursor++; @@ -307,6 +325,13 @@ public class FHIRLexer { return processConstant(take()); } + public String readFixedName(String desc) throws FHIRLexerException { + if (!isFixedName()) + throw error("Found "+current+" expecting \"["+desc+"]\""); + + return processFixedName(take()); + } + public String processConstant(String s) throws FHIRLexerException { StringBuilder b = new StringBuilder(); int i = 1; @@ -337,7 +362,7 @@ public class FHIRLexer { b.append('\\'); break; case '/': - b.append('\\'); + b.append('/'); break; case 'u': i++; @@ -354,8 +379,57 @@ public class FHIRLexer { } } return b.toString(); - } + + public String processFixedName(String s) throws FHIRLexerException { + StringBuilder b = new StringBuilder(); + int i = 1; + while (i < s.length()-1) { + char ch = s.charAt(i); + if (ch == '\\') { + i++; + switch (s.charAt(i)) { + case 't': + b.append('\t'); + break; + case 'r': + b.append('\r'); + break; + case 'n': + b.append('\n'); + break; + case 'f': + b.append('\f'); + break; + case '\'': + b.append('\''); + break; + case '"': + b.append('"'); + break; + case '\\': + b.append('\\'); + break; + case '/': + b.append('/'); + break; + case 'u': + i++; + int uc = Integer.parseInt(s.substring(i, i+4), 16); + b.append((char) uc); + i = i + 4; + break; + default: + throw new FHIRLexerException("Unknown character escape \\"+s.charAt(i)); + } + } else { + b.append(ch); + i++; + } + } + return b.toString(); + } + public void skipToken(String token) throws FHIRLexerException { if (getCurrent().equals(token)) next(); diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java index c974acbf4..3521e5d6f 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/FHIRPathEngine.java @@ -806,7 +806,7 @@ public class FHIRPathEngine { lexer.take(); lexer.setCurrent("+"+lexer.getCurrent()); } - if (lexer.isConstant(false)) { + if (lexer.isConstant()) { boolean isString = lexer.isStringConstant(); result.setConstant(processConstant(lexer)); result.setKind(Kind.Constant); @@ -845,10 +845,10 @@ public class FHIRPathEngine { result.setEnd(lexer.getCurrentLocation()); lexer.next(); } else { - if (!lexer.isToken() && !lexer.getCurrent().startsWith("\"")) + if (!lexer.isToken() && !lexer.getCurrent().startsWith("`")) throw lexer.error("Found "+lexer.getCurrent()+" expecting a token name"); - if (lexer.getCurrent().startsWith("\"")) - result.setName(lexer.readConstant("Path Name")); + if (lexer.isFixedName()) + result.setName(lexer.readFixedName("Path Name")); else result.setName(lexer.take()); result.setEnd(lexer.getCurrentLocation()); diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java index f29cbee76..1e08cdc01 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java @@ -1013,7 +1013,7 @@ public class StructureMapUtilities { // no dependencies - imply what is to be done based on types } if (newFmt) { - if (lexer.isConstant(true)) { + if (lexer.isConstant()) { rule.setName(lexer.take()); } else { if (rule.getSource().size() != 1 || !rule.getSourceFirstRep().hasElement()) @@ -1120,7 +1120,7 @@ public class StructureMapUtilities { if (start != null) target.setContext(start); lexer.token("="); - isConstant = lexer.isConstant(true); + isConstant = lexer.isConstant(); name = lexer.take(); } else name = start; @@ -1180,7 +1180,7 @@ public class StructureMapUtilities { private void parseParameter(StructureMapGroupRuleTargetComponent target, FHIRLexer lexer) throws FHIRLexerException, FHIRFormatError { - if (!lexer.isConstant(true)) { + if (!lexer.isConstant()) { target.addParameter().setValue(new IdType(lexer.take())); } else if (lexer.isStringConstant()) target.addParameter().setValue(new StringType(lexer.readConstant("??"))); diff --git a/org.hl7.fhir.r4/src/test/resources/fhirpath/tests-fhir-r4.xml b/org.hl7.fhir.r4/src/test/resources/fhirpath/tests-fhir-r4.xml index d6e190431..ea3b58acc 100644 --- a/org.hl7.fhir.r4/src/test/resources/fhirpath/tests-fhir-r4.xml +++ b/org.hl7.fhir.r4/src/test/resources/fhirpath/tests-fhir-r4.xml @@ -38,8 +38,8 @@ - - name."given" + + name.`given` Peter James Jim