Class Parser
- java.lang.Object
-
- org.openjdk.asmtools.jasm.ParseBase
-
- org.openjdk.asmtools.jasm.Parser
-
class Parser extends ParseBase
This class is used to parse Jasm statements and expressions. The result is a parse tree.This class implements an operator precedence parser. Errors are reported to the Environment object, if the error can't be resolved immediately, a SyntaxError exception is thrown.
Error recovery is implemented by catching Scanner.SyntaxError exceptions and discarding input scanner.tokens until an input token is reached that is possibly a legal continuation.
The parse tree that is constructed represents the input exactly (no rewrites to simpler forms). This is important if the resulting tree is to be used for code formatting in a programming environment. Currently only documentation comments are retained.
A parser owns several components (scanner, constant-parser, instruction-parser, annotations-parser) to which it delegates certain parsing responsibilities. This parser contains functions to parse the overall form of a class, and any members (fields, methods, inner-classes).
Syntax errors, should always be caught inside the parser for error recovery.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) static class
Parser.CompilerError
The main compile error for the parser(package private) static interface
Parser.Method
(package private) static interface
Parser.NameSupplier
-
Field Summary
Fields Modifier and Type Field Description private ParserAnnotation
annotParser
other parser components(package private) ClassData
cd
private java.util.ArrayList<AnnotationData>
clsAnnttns
private java.util.ArrayList<ClassData>
clsDataList
private ParserCP
cpParser
(package private) CodeAttr
curCode
private CFVersion
currentCFV
private boolean
explicitcp
private ParserInstr
instrParser
private java.util.ArrayList<AnnotationData>
memberAnnttns
private ModuleAttr
moduleAttribute
private java.lang.String
pkg
private java.util.ArrayList<AnnotationData>
pkgAnnttns
private java.lang.String
pkgPrefix
protected ConstantPool
pool
-
Constructor Summary
Constructors Modifier Constructor Description protected
Parser(Environment sf, CFVersion cfVersion)
Create a parser
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private void
checkReferenceIndex(int position, Tables.ConstType defaultTag, Tables.ConstType default2Tag)
Check the pair reference_kind:reference_index where reference_kind is any from: REF_invokeVirtual, REF_newInvokeSpecial, REF_invokeStatic, REF_invokeSpecial, REF_invokeInterface and reference_index is one of [Empty], Method or InterfaceMethod There are possible entries: ldc Dynamic REF_newInvokeSpecial:InterfaceMethod LdcConDyTwice."": ldc Dynamic REF_invokeInterface:LdcConDyTwice." ": ldc Dynamic REF_newInvokeSpecial:Method LdcConDyTwice." ": ldc MethodHandle REF_newInvokeSpecial:InterfaceMethod LdcConDyTwice." ": ldc MethodHandle REF_invokeInterface:LdcConDyTwice." ": ldc MethodHandle REF_newInvokeSpecial:Method LdcConDyTwice." ": invokedynamic MethodHandle REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants: invokedynamic MethodHandle REF_invokeStatic:java/lang/invoke/StringConcatFactory.makeConcatWithConstants .... private int
countParams(ConstantPool.ConstCell sigCell)
Scan method's signature to determine size of parameters.(package private) java.lang.String
encodeClassString(java.lang.String classname)
private void
endClass()
End classprivate void
endModule()
End module(package private) ClassData[]
getClassesData()
private void
match(JasmTokens.Token open, JasmTokens.Token close)
The match() method is used to quickly match opening brackets (ie: '(', '{', or '[') with their closing counter part.private void
parseClass(int mod)
Parse a class or interface declaration.private void
parseClasses(java.util.function.Consumer<java.util.ArrayList<ConstantPool.ConstCell>> classesConsumer)
Parse a list of classes belonging to the [NestMembers | PermittedSubclasses] entryprivate void
parseClassMembers()
(package private) ConstantPool.ConstCell
parseClassName(boolean uncond)
private void
parseConstDef()
Parse constant declarationprivate void
parseCPXBootstrapMethod()
Parse a (CPX based) BootstrapMethod entry.private void
parseField(int mod)
Parse a field.(package private) void
parseFile()
Parse an Jasm file.(package private) java.lang.String
parseIdent()
Parse an internal name: identifier.private void
parseInnerClass(int mod)
Parse an inner class.private void
parseInnerClass_s1(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass)
private void
parseInnerClass_s2(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass)
private void
parseInnerClass_s3(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass)
(package private) Argument
parseInt(int size)
Parse a signed integer of size bytes long.private void
parseJasmPackages()
Determines whether the JASM file is for a package-info class or for a module-info class.(package private) void
parseLocVarDef()
Parse a local variable(package private) void
parseLocVarEnd()
(package private) Argument
parseLocVarRef()
(package private) void
parseMapItem(DataVector map)
private void
parseMethod(int mod)
Parse a method.(package private) ConstantPool.ConstCell
parseMethodHandle(Tables.SubTag subtag)
Parses a field or method reference for method handle.private void
parseModule()
Parse a module declaration.private java.lang.String
parseModuleName()
Parses a module name in a module statement(s)(package private) ConstantPool.ConstCell
parseName()
Parse an external name: CPINDEX, string, or identifier.private void
parseNestHost()
Parse a NestHost entryprivate void
parseRecord()
Parse the Record entry(package private) Tables.SubTag
parseSubtag()
Parses a sub-tag value in method handle.private java.lang.String
parseTypeName()
Parses a package or type name in a module statement(s)(package private) Argument
parseUInt(int size)
Parse an unsigned integer of size bytes long.private void
parseVersion()
private void
parseVersionPkg()
Parses version in package statementsprivate void
pic_error()
private void
pic_tracecreate(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass)
private java.lang.String
prependPackage(java.lang.String className, boolean uncond)
private void
recoverField()
Recover after a syntax error in a field.private void
recoverFile()
Recover after a syntax error in the file.private java.util.HashSet<java.lang.String>
scanList(Parser.Method scanMethod, Parser.NameSupplier target, java.lang.String err, boolean onlyOneElement)
Scans the "to" or "with" part of ModuleStatement: exports PackageName [to ModuleName {, ModuleName}] ;, opens packageName [to ModuleName {, ModuleName}] ; provides TypeName with TypeName [,typeName] ; uses TypeName; : [ModuleName {, ModuleName}]; , [TypeName [,typeName]]; or TypeName;private int
scanModifier(int mod)
Parse the modifiers(package private) int
scanModifiers()
private void
scanRequires(java.util.function.BiConsumer<java.lang.String,java.lang.Integer> action)
Scans ModuleStatement: requires [transitive] [static] ModuleName ;private void
scanStatement(java.util.function.BiConsumer<java.lang.String,java.util.Set<java.lang.String>> action, Parser.NameSupplier source, Parser.NameSupplier target, JasmTokens.Token startList, boolean emptyListAllowed, java.lang.String err)
Scans Module Statement(s): exports packageName [to ModuleName {, ModuleName}] ; opens packageName [to ModuleName {, ModuleName}] ; provides TypeName with TypeName [,typeName] ;private void
scanStatement(java.util.function.Consumer<java.util.Set<java.lang.String>> action, java.lang.String err)
Scans ModuleStatement: uses TypeName;(package private) void
setDebugFlags(boolean debugScanner, boolean debugMembers, boolean debugCP, boolean debugAnnot, boolean debugInstr)
-
Methods inherited from class org.openjdk.asmtools.jasm.ParseBase
debugScan, debugStr, enableDebug, init
-
-
-
-
Field Detail
-
pool
protected ConstantPool pool
-
cd
ClassData cd
-
curCode
CodeAttr curCode
-
clsDataList
private java.util.ArrayList<ClassData> clsDataList
-
pkg
private java.lang.String pkg
-
pkgPrefix
private java.lang.String pkgPrefix
-
pkgAnnttns
private java.util.ArrayList<AnnotationData> pkgAnnttns
-
clsAnnttns
private java.util.ArrayList<AnnotationData> clsAnnttns
-
memberAnnttns
private java.util.ArrayList<AnnotationData> memberAnnttns
-
explicitcp
private boolean explicitcp
-
moduleAttribute
private ModuleAttr moduleAttribute
-
currentCFV
private CFVersion currentCFV
-
annotParser
private ParserAnnotation annotParser
other parser components
-
cpParser
private ParserCP cpParser
-
instrParser
private ParserInstr instrParser
-
-
Constructor Detail
-
Parser
protected Parser(Environment sf, CFVersion cfVersion) throws java.io.IOException
Create a parser- Throws:
java.io.IOException
-
-
Method Detail
-
setDebugFlags
void setDebugFlags(boolean debugScanner, boolean debugMembers, boolean debugCP, boolean debugAnnot, boolean debugInstr)
-
encodeClassString
java.lang.String encodeClassString(java.lang.String classname)
-
parseVersionPkg
private void parseVersionPkg() throws java.io.IOException
Parses version in package statements- Throws:
java.io.IOException
-
parseVersion
private void parseVersion() throws java.io.IOException
- Throws:
java.io.IOException
-
parseIdent
java.lang.String parseIdent() throws Scanner.SyntaxError, java.io.IOException
Parse an internal name: identifier.- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseLocVarDef
void parseLocVarDef() throws Scanner.SyntaxError, java.io.IOException
Parse a local variable- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseLocVarRef
Argument parseLocVarRef() throws Scanner.SyntaxError, java.io.IOException
- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseLocVarEnd
void parseLocVarEnd() throws Scanner.SyntaxError, java.io.IOException
- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseMapItem
void parseMapItem(DataVector map) throws Scanner.SyntaxError, java.io.IOException
- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseName
ConstantPool.ConstCell parseName() throws Scanner.SyntaxError, java.io.IOException
Parse an external name: CPINDEX, string, or identifier.- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseMethodHandle
ConstantPool.ConstCell parseMethodHandle(Tables.SubTag subtag) throws Scanner.SyntaxError, java.io.IOException
Parses a field or method reference for method handle.- Throws:
Scanner.SyntaxError
java.io.IOException
-
checkReferenceIndex
private void checkReferenceIndex(int position, Tables.ConstType defaultTag, Tables.ConstType default2Tag)
Check the pair reference_kind:reference_index where reference_kind is any from: REF_invokeVirtual, REF_newInvokeSpecial, REF_invokeStatic, REF_invokeSpecial, REF_invokeInterface and reference_index is one of [Empty], Method or InterfaceMethod There are possible entries: ldc Dynamic REF_newInvokeSpecial:InterfaceMethod LdcConDyTwice."": ldc Dynamic REF_invokeInterface:LdcConDyTwice." ": ldc Dynamic REF_newInvokeSpecial:Method LdcConDyTwice." ": ldc MethodHandle REF_newInvokeSpecial:InterfaceMethod LdcConDyTwice." ": ldc MethodHandle REF_invokeInterface:LdcConDyTwice." ": ldc MethodHandle REF_newInvokeSpecial:Method LdcConDyTwice." ": invokedynamic MethodHandle REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants: invokedynamic MethodHandle REF_invokeStatic:java/lang/invoke/StringConcatFactory.makeConcatWithConstants .... - Parameters:
position
- the position in a source filedefaultTag
- expected reference_index tag (Method or InterfaceMethod)defaultTag
- 2nd expected reference_index tag (Method or InterfaceMethod)
-
parseSubtag
Tables.SubTag parseSubtag() throws Scanner.SyntaxError, java.io.IOException
Parses a sub-tag value in method handle.- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseClassName
ConstantPool.ConstCell parseClassName(boolean uncond) throws Scanner.SyntaxError, java.io.IOException
- Throws:
Scanner.SyntaxError
java.io.IOException
-
prependPackage
private java.lang.String prependPackage(java.lang.String className, boolean uncond)
-
parseInt
Argument parseInt(int size) throws Scanner.SyntaxError, java.io.IOException
Parse a signed integer of size bytes long. size = 1 or 2- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseUInt
Argument parseUInt(int size) throws Scanner.SyntaxError, java.io.IOException
Parse an unsigned integer of size bytes long. size = 1 or 2- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseConstDef
private void parseConstDef() throws java.io.IOException
Parse constant declaration- Throws:
java.io.IOException
-
scanModifier
private int scanModifier(int mod) throws java.io.IOException
Parse the modifiers- Throws:
java.io.IOException
-
scanModifiers
int scanModifiers() throws java.io.IOException
- Throws:
java.io.IOException
-
parseField
private void parseField(int mod) throws Scanner.SyntaxError, java.io.IOException
Parse a field.- Throws:
Scanner.SyntaxError
java.io.IOException
-
countParams
private int countParams(ConstantPool.ConstCell sigCell) throws Scanner.SyntaxError
Scan method's signature to determine size of parameters.- Throws:
Scanner.SyntaxError
-
parseMethod
private void parseMethod(int mod) throws Scanner.SyntaxError, java.io.IOException
Parse a method.- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseCPXBootstrapMethod
private void parseCPXBootstrapMethod() throws Scanner.SyntaxError, java.io.IOException
Parse a (CPX based) BootstrapMethod entry.- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseNestHost
private void parseNestHost() throws Scanner.SyntaxError, java.io.IOException
Parse a NestHost entry- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseClasses
private void parseClasses(java.util.function.Consumer<java.util.ArrayList<ConstantPool.ConstCell>> classesConsumer) throws Scanner.SyntaxError, java.io.IOException
Parse a list of classes belonging to the [NestMembers | PermittedSubclasses] entry- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseRecord
private void parseRecord() throws Scanner.SyntaxError, java.io.IOException
Parse the Record entry- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseInnerClass
private void parseInnerClass(int mod) throws Scanner.SyntaxError, java.io.IOException
Parse an inner class.- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseInnerClass_s1
private void parseInnerClass_s1(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass) throws java.io.IOException
- Throws:
java.io.IOException
-
parseInnerClass_s2
private void parseInnerClass_s2(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass) throws java.io.IOException
- Throws:
java.io.IOException
-
parseInnerClass_s3
private void parseInnerClass_s3(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass) throws java.io.IOException
- Throws:
java.io.IOException
-
pic_tracecreate
private void pic_tracecreate(int mod, ConstantPool.ConstCell nameCell, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass)
-
pic_error
private void pic_error()
-
match
private void match(JasmTokens.Token open, JasmTokens.Token close) throws java.io.IOException
The match() method is used to quickly match opening brackets (ie: '(', '{', or '[') with their closing counter part. This is useful during error recovery.Scan to a matching '}', ']' or ')'. The current scanner.token must be a '{', '[' or '(';
- Throws:
java.io.IOException
-
recoverField
private void recoverField() throws Scanner.SyntaxError, java.io.IOException
Recover after a syntax error in a field. This involves discarding scanner.tokens until an EOF or a possible legal continuation is encountered.- Throws:
Scanner.SyntaxError
java.io.IOException
-
parseClass
private void parseClass(int mod) throws java.io.IOException
Parse a class or interface declaration.- Throws:
java.io.IOException
-
parseTypeName
private java.lang.String parseTypeName() throws java.io.IOException
Parses a package or type name in a module statement(s)- Throws:
java.io.IOException
-
parseModuleName
private java.lang.String parseModuleName() throws java.io.IOException
Parses a module name in a module statement(s)- Throws:
java.io.IOException
-
parseModule
private void parseModule() throws java.io.IOException
Parse a module declaration.- Throws:
java.io.IOException
-
scanRequires
private void scanRequires(java.util.function.BiConsumer<java.lang.String,java.lang.Integer> action) throws java.io.IOException
Scans ModuleStatement: requires [transitive] [static] ModuleName ;- Throws:
java.io.IOException
-
scanStatement
private void scanStatement(java.util.function.Consumer<java.util.Set<java.lang.String>> action, java.lang.String err) throws java.io.IOException
Scans ModuleStatement: uses TypeName;- Throws:
java.io.IOException
-
scanStatement
private void scanStatement(java.util.function.BiConsumer<java.lang.String,java.util.Set<java.lang.String>> action, Parser.NameSupplier source, Parser.NameSupplier target, JasmTokens.Token startList, boolean emptyListAllowed, java.lang.String err) throws java.io.IOException
Scans Module Statement(s): exports packageName [to ModuleName {, ModuleName}] ; opens packageName [to ModuleName {, ModuleName}] ; provides TypeName with TypeName [,typeName] ;- Throws:
java.io.IOException
-
scanList
private java.util.HashSet<java.lang.String> scanList(Parser.Method scanMethod, Parser.NameSupplier target, java.lang.String err, boolean onlyOneElement) throws java.io.IOException
Scans the "to" or "with" part of ModuleStatement: exports PackageName [to ModuleName {, ModuleName}] ;, opens packageName [to ModuleName {, ModuleName}] ; provides TypeName with TypeName [,typeName] ; uses TypeName; : [ModuleName {, ModuleName}]; , [TypeName [,typeName]]; or TypeName;- Throws:
java.io.IOException
-
parseClassMembers
private void parseClassMembers() throws java.io.IOException
- Throws:
java.io.IOException
-
recoverFile
private void recoverFile() throws java.io.IOException
Recover after a syntax error in the file. This involves discarding scanner.tokens until an EOF or a possible legal continuation is encountered.- Throws:
java.io.IOException
-
endClass
private void endClass()
End class
-
endModule
private void endModule()
End module
-
getClassesData
final ClassData[] getClassesData()
-
parseJasmPackages
private void parseJasmPackages() throws java.io.IOException
Determines whether the JASM file is for a package-info class or for a module-info class.creates the correct kind of ClassData accordingly.
- Throws:
java.io.IOException
-
parseFile
void parseFile()
Parse an Jasm file.
-
-