From 1972b7171e8f93b0ca2a7335b078753358fda3cf Mon Sep 17 00:00:00 2001 From: kas0079 Date: Sat, 4 Jan 2025 22:38:12 +0100 Subject: [PATCH 1/4] fix the ParsingContext of serviceNode --- libjolie/src/main/java/jolie/lang/parse/OLParser.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libjolie/src/main/java/jolie/lang/parse/OLParser.java b/libjolie/src/main/java/jolie/lang/parse/OLParser.java index 8e1298e05..40a4481b8 100644 --- a/libjolie/src/main/java/jolie/lang/parse/OLParser.java +++ b/libjolie/src/main/java/jolie/lang/parse/OLParser.java @@ -1688,6 +1688,9 @@ private void parseService() } setEndLine(); // remember end line for error eat( Scanner.TokenType.RCURLY, "expected }" ); + + ctx = new URIParsingContext( ctx.source(), ctx.startLine(), endLine(), ctx.startColumn(), errorColumn(), + ctx.enclosingCode() ); // it is a Jolie internal service if( internalIfaces != null && internalIfaces.length > 0 ) { if( internalMain == null ) { From 51a6cfefef5a2e9856c84ec37048d8f9e3365820 Mon Sep 17 00:00:00 2001 From: kas0079 Date: Wed, 8 Jan 2025 05:09:05 +0100 Subject: [PATCH 2/4] initial draft of lambda function --- .../main/java/jolie/lang/parse/OLParser.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/libjolie/src/main/java/jolie/lang/parse/OLParser.java b/libjolie/src/main/java/jolie/lang/parse/OLParser.java index 40a4481b8..ea97290c6 100644 --- a/libjolie/src/main/java/jolie/lang/parse/OLParser.java +++ b/libjolie/src/main/java/jolie/lang/parse/OLParser.java @@ -41,7 +41,9 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; //import jolie.lang.CodeCheckMessage; @@ -1557,6 +1559,23 @@ private ServiceNode createJolieServiceNode( return node; } + /** + * Parses the internals for the creation of a Node, creates the Node and inserts it into the ProgramBuilder. + * @param internalsParser A lambda that parses the internals of a Node. + * @param nodeAdder A lambda which creates the Node itself from its internals and a ParsingContext. + * It must also add the node into the programBuilder. //TODO consider doing that in the function. + * @param Type for the internals required to create the Node in question. + */ + private void parseInternals( Supplier internalsParser, BiConsumer nodeAdder) + throws IOException, ParserException { + ParsingContext earlyContext = getContext(); + I internals = internalsParser.apply(earlyContext); + ParsingContext finalContext = new URIParsingContext( scanner().source(), earlyContext.startLine(), endLine(), + earlyContext.startColumn(), errorColumn(), + earlyContext.enclosingCode() ); + nodeAdder.accept(internals, finalContext); + } + /** * Parses a service node, i.e. service service_name ( varpath : type ) {} */ @@ -1580,7 +1599,8 @@ private void parseService() setEndLine(); // remember endline of parsing service for error assertToken( Scanner.TokenType.ID, "expected service name" ); - ParsingContext ctx = getContext(); + // We don't know where the Service ends yet, but we need to remember where it started + ParsingContext earlyContext = getContext(); String serviceName = token.content(); nextToken(); @@ -1689,8 +1709,9 @@ private void parseService() setEndLine(); // remember end line for error eat( Scanner.TokenType.RCURLY, "expected }" ); - ctx = new URIParsingContext( ctx.source(), ctx.startLine(), endLine(), ctx.startColumn(), errorColumn(), - ctx.enclosingCode() ); + ParsingContext ctx = new URIParsingContext( scanner().source(), earlyContext.startLine(), endLine(), + earlyContext.startColumn(), errorColumn(), + earlyContext.enclosingCode() ); // it is a Jolie internal service if( internalIfaces != null && internalIfaces.length > 0 ) { if( internalMain == null ) { From 15dfc5d89d8f66fc4e586222626ce05ff756f427 Mon Sep 17 00:00:00 2001 From: kas0079 Date: Mon, 13 Jan 2025 03:49:01 +0100 Subject: [PATCH 3/4] Wrapper for generating parsing contexts --- .../main/java/jolie/lang/parse/OLParser.java | 270 ++++++++++-------- 1 file changed, 150 insertions(+), 120 deletions(-) diff --git a/libjolie/src/main/java/jolie/lang/parse/OLParser.java b/libjolie/src/main/java/jolie/lang/parse/OLParser.java index ea97290c6..e803ad0a2 100644 --- a/libjolie/src/main/java/jolie/lang/parse/OLParser.java +++ b/libjolie/src/main/java/jolie/lang/parse/OLParser.java @@ -41,9 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; +import java.util.function.*; import java.util.stream.Collectors; //import jolie.lang.CodeCheckMessage; @@ -1560,20 +1558,39 @@ private ServiceNode createJolieServiceNode( } /** - * Parses the internals for the creation of a Node, creates the Node and inserts it into the ProgramBuilder. + * A functional interface for parsing the internals of a Node. Identical to Supplier except with + * some needed exceptions. + * + * @see java.util.function.Supplier + * @param Class containing the results of the parsing + */ + @FunctionalInterface + private interface ParsingLambda< T > { + /** + * Performs the parsing + * + * @return The result of the parsing + */ + T get() throws IOException, ParserException; + } + private record InternalParseResult< I >(I internals, ParsingContext context) { + } + + /** + * Parses the internals for the creation of a Node and creates an appropriate ParsingContext + * * @param internalsParser A lambda that parses the internals of a Node. - * @param nodeAdder A lambda which creates the Node itself from its internals and a ParsingContext. - * It must also add the node into the programBuilder. //TODO consider doing that in the function. * @param Type for the internals required to create the Node in question. */ - private void parseInternals( Supplier internalsParser, BiConsumer nodeAdder) + private < I > InternalParseResult< I > parseInternals( ParsingLambda< I > internalsParser ) throws IOException, ParserException { ParsingContext earlyContext = getContext(); - I internals = internalsParser.apply(earlyContext); + I internals = internalsParser.get(); + setEndLine(); ParsingContext finalContext = new URIParsingContext( scanner().source(), earlyContext.startLine(), endLine(), earlyContext.startColumn(), errorColumn(), earlyContext.enclosingCode() ); - nodeAdder.accept(internals, finalContext); + return new InternalParseResult<>( internals, finalContext ); } /** @@ -1591,134 +1608,147 @@ private void parseService() nextToken(); return; } - setStartLine(); // remember line we started parsing service at - nextToken(); - - Constants.EmbeddedServiceType tech = Constants.EmbeddedServiceType.SERVICENODE; Map< String, String > configMap = new HashMap<>(); + record Internals(Constants.EmbeddedServiceType tech, InterfaceDefinition[] internalIfaces, + DefinitionNode internalMain, SequenceStatement internalInit, + ProgramBuilder serviceBlockProgramBuilder, String serviceName, Pair< String, TypeDefinition > parameter) { + } + InternalParseResult< Internals > parseResult = parseInternals( () -> { + setStartLine(); // remember line we started parsing service at + nextToken(); - setEndLine(); // remember endline of parsing service for error - assertToken( Scanner.TokenType.ID, "expected service name" ); - // We don't know where the Service ends yet, but we need to remember where it started - ParsingContext earlyContext = getContext(); - String serviceName = token.content(); - nextToken(); + Constants.EmbeddedServiceType tech = Constants.EmbeddedServiceType.SERVICENODE; - Pair< String, TypeDefinition > parameter = parseServiceParameter(); + setEndLine(); // remember endline of parsing service for error + assertToken( Scanner.TokenType.ID, "expected service name" ); + String serviceName = token.content(); + nextToken(); - setEndLine();// remember endline of parsing service for error - // look for curly bracket with scope and scopeName in case of error - eat( Scanner.TokenType.LCURLY, "expected {", serviceName, Keywords.SERVICE ); - // jolie internal service's Interface - InterfaceDefinition[] internalIfaces = null; + Pair< String, TypeDefinition > parameter = parseServiceParameter(); - DefinitionNode internalMain = null; - SequenceStatement internalInit = null; + setEndLine();// remember endline of parsing service for error + // look for curly bracket with scope and scopeName in case of error + eat( Scanner.TokenType.LCURLY, "expected {", serviceName, Keywords.SERVICE ); + // jolie internal service's Interface + InterfaceDefinition[] internalIfaces = null; - ProgramBuilder serviceBlockProgramBuilder = new ProgramBuilder( getContext() ); - boolean keepRun = true; + DefinitionNode internalMain = null; + SequenceStatement internalInit = null; - while( keepRun ) { - Optional< Scanner.Token > internalForwardDocToken = parseForwardDocumentation(); - switch( token.content() ) { - case "Interfaces": // internal service node syntax - internalIfaces = parseInternalServiceInterface(); - break; - case "include": - parseInclude(); - break; - case "cset": - for( CorrelationSetInfo csetInfo : _parseCorrelationSets() ) { - serviceBlockProgramBuilder.addChild( csetInfo ); - } - break; - case "execution": - serviceBlockProgramBuilder.addChild( _parseExecutionInfo() ); - break; - case "courier": - serviceBlockProgramBuilder.addChild( parseCourierDefinition() ); - break; - case "init": - if( internalInit == null ) { - internalInit = new SequenceStatement( getContext() ); - } - internalInit.addChild( parseInit() ); - break; - case "main": - // remember start and end line for error - setStartLine(); - setEndLine(); - if( internalMain != null ) { - throwException( "you must specify only one main definition" ); - } - internalMain = parseMain(); - break; - case "inputPort": - case "outputPort": - PortInfo p = _parsePort(); - parseBackwardAndSetDocumentation( p, internalForwardDocToken ); - serviceBlockProgramBuilder.addChild( p ); - break; - case "define": - serviceBlockProgramBuilder.addChild( parseDefinition() ); - break; - case "embed": - EmbedServiceNode embedServiceNode = parseEmbeddedServiceNode(); - if( embedServiceNode.isNewPort() ) { - serviceBlockProgramBuilder - .addChild( embedServiceNode.bindingPort() ); - } - serviceBlockProgramBuilder.addChild( embedServiceNode ); - break; - case "foreign": - nextToken(); - String technology = token.content(); - if( technology.equals( "java" ) ) { - tech = Constants.EmbeddedServiceType.SERVICENODE_JAVA; - } - nextToken(); - eat( Scanner.TokenType.LCURLY, "expected {" ); - while( token.isNot( Scanner.TokenType.RCURLY ) ) { - String key = token.content(); + ProgramBuilder serviceBlockProgramBuilder = new ProgramBuilder( getContext() ); + + boolean keepRun = true; + + while( keepRun ) { + Optional< Scanner.Token > internalForwardDocToken = parseForwardDocumentation(); + switch( token.content() ) { + case "Interfaces": // internal service node syntax + internalIfaces = parseInternalServiceInterface(); + break; + case "include": + parseInclude(); + break; + case "cset": + for( CorrelationSetInfo csetInfo : _parseCorrelationSets() ) { + serviceBlockProgramBuilder.addChild( csetInfo ); + } + break; + case "execution": + serviceBlockProgramBuilder.addChild( _parseExecutionInfo() ); + break; + case "courier": + serviceBlockProgramBuilder.addChild( parseCourierDefinition() ); + break; + case "init": + if( internalInit == null ) { + internalInit = new SequenceStatement( getContext() ); + } + internalInit.addChild( parseInit() ); + break; + case "main": + // remember start and end line for error + setStartLine(); + setEndLine(); + if( internalMain != null ) { + throwException( "you must specify only one main definition" ); + } + internalMain = parseMain(); + break; + case "inputPort": + case "outputPort": + PortInfo p = _parsePort(); + parseBackwardAndSetDocumentation( p, internalForwardDocToken ); + serviceBlockProgramBuilder.addChild( p ); + break; + case "define": + serviceBlockProgramBuilder.addChild( parseDefinition() ); + break; + case "embed": + EmbedServiceNode embedServiceNode = parseEmbeddedServiceNode(); + if( embedServiceNode.isNewPort() ) { + serviceBlockProgramBuilder + .addChild( embedServiceNode.bindingPort() ); + } + serviceBlockProgramBuilder.addChild( embedServiceNode ); + break; + case "foreign": nextToken(); - eat( Scanner.TokenType.COLON, "expected :" ); - String value = ""; - while( !hasMetNewline() ) { - if( token.is( Scanner.TokenType.DOT ) ) { - value += "."; - } else { - value += token.content(); - } + String technology = token.content(); + if( technology.equals( "java" ) ) { + tech = Constants.EmbeddedServiceType.SERVICENODE_JAVA; + } + nextToken(); + eat( Scanner.TokenType.LCURLY, "expected {" ); + while( token.isNot( Scanner.TokenType.RCURLY ) ) { + String key = token.content(); nextToken(); + eat( Scanner.TokenType.COLON, "expected :" ); + String value = ""; + while( !hasMetNewline() ) { + if( token.is( Scanner.TokenType.DOT ) ) { + value += "."; + } else { + value += token.content(); + } + nextToken(); + } + configMap.put( key, value ); } - configMap.put( key, value ); - } - setEndLine(); // remember end line for error - eat( Scanner.TokenType.RCURLY, "expected }" ); - default: - setEndLine(); // remember end line for error - if( token.isNot( Scanner.TokenType.EOF ) ) { - setStartLine(); // remember start line for error + setEndLine(); // remember end line for error + eat( Scanner.TokenType.RCURLY, "expected }" ); + default: + setEndLine(); // remember end line for error + if( token.isNot( Scanner.TokenType.EOF ) ) { + setStartLine(); // remember start line for error + } + // assert with scopeName and scope in case of error + assertToken( Scanner.TokenType.RCURLY, "unexpected term found inside service " + serviceName, + serviceName, "service" ); + keepRun = false; } - // assert with scopeName and scope in case of error - assertToken( Scanner.TokenType.RCURLY, "unexpected term found inside service " + serviceName, - serviceName, "service" ); - keepRun = false; } - } - setEndLine(); // remember end line for error - eat( Scanner.TokenType.RCURLY, "expected }" ); + setEndLine(); // remember end line for error + eat( Scanner.TokenType.RCURLY, "expected }" ); + return new Internals( tech, internalIfaces, internalMain, internalInit, serviceBlockProgramBuilder, + serviceName, parameter ); + } ); + + Internals internals = parseResult.internals(); + InterfaceDefinition[] internalIfaces = internals.internalIfaces(); + DefinitionNode internalMain = internals.internalMain(); + SequenceStatement internalInit = internals.internalInit(); + ProgramBuilder serviceBlockProgramBuilder = internals.serviceBlockProgramBuilder(); + String serviceName = internals.serviceName(); + Pair< String, TypeDefinition > parameter = internals.parameter(); + Constants.EmbeddedServiceType tech = internals.tech(); - ParsingContext ctx = new URIParsingContext( scanner().source(), earlyContext.startLine(), endLine(), - earlyContext.startColumn(), errorColumn(), - earlyContext.enclosingCode() ); // it is a Jolie internal service if( internalIfaces != null && internalIfaces.length > 0 ) { if( internalMain == null ) { setEndLine(); // remember end line for error throwException( "You must specify a main for service " + serviceName ); } - EmbeddedServiceNode node = createInternalService( ctx, serviceName, internalIfaces, + EmbeddedServiceNode node = createInternalService( parseResult.context(), serviceName, internalIfaces, internalInit, internalMain, programBuilder ); programBuilder.addChild( node ); } else { @@ -1731,7 +1761,7 @@ private void parseService() switch( tech ) { case SERVICENODE: serviceNode = createJolieServiceNode( - ctx, + parseResult.context(), serviceName, parameter, accessModifier, @@ -1742,7 +1772,7 @@ private void parseService() break; default: serviceNode = createForeignServiceNode( - ctx, + parseResult.context(), serviceName, parameter, accessModifier, From 13af7f78930e203fbece427aed3bacfa5f9f9880 Mon Sep 17 00:00:00 2001 From: kas0079 Date: Fri, 7 Feb 2025 05:34:55 +0100 Subject: [PATCH 4/4] revert import * in OLParser --- libjolie/src/main/java/jolie/lang/parse/OLParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libjolie/src/main/java/jolie/lang/parse/OLParser.java b/libjolie/src/main/java/jolie/lang/parse/OLParser.java index e803ad0a2..a50baa5a2 100644 --- a/libjolie/src/main/java/jolie/lang/parse/OLParser.java +++ b/libjolie/src/main/java/jolie/lang/parse/OLParser.java @@ -41,7 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.*; +import java.util.function.Function; import java.util.stream.Collectors; //import jolie.lang.CodeCheckMessage;