Parser

R

Roedy Green

What is considered the best parser nowadays that generates the parser
in Java source code?

What I need in an abbreviated Java parser just to cut the program into
chunks, each class within that each declaration and method.

I have already written the parsing that takes it from there.

The idea is to rearrange your code in a defined canonical order,
e.g. statics before instance primitives before references, char before
int...

If I were designing Java, I would have put a keyword on the front of
each declaration e.g. dcl, and each method "method".

This would make parsing simpler and faster. It would also make
navigating with a simple search string easier. IF the keyword were
shown in special colour, it would make it much easier by eye to detect
method starts.
 
J

Jeff Higgins

What is considered the best parser nowadays that generates the parser
in Java source code?

What I need in an abbreviated Java parser just to cut the program into
chunks, each class within that each declaration and method.

I have already written the parsing that takes it from there.

The idea is to rearrange your code in a defined canonical order,
e.g. statics before instance primitives before references, char before
int...

If I were designing Java, I would have put a keyword on the front of
each declaration e.g. dcl, and each method "method".

This would make parsing simpler and faster. It would also make
navigating with a simple search string easier. IF the keyword were
shown in special colour, it would make it much easier by eye to detect
method starts.

Not parser generator but some issues to be aware of.
<http://openjdk.java.net/projects/compiler-grammar/>
 
J

Jeff Higgins

On 04/27/2014 07:59 PM, Jeff Higgins wrote:

The Java® Language Specification Java SE 8 Edition
Chapter 19. Syntax
<http://docs.oracle.com/javase/specs/jls/se8/html/jls-19.html>

Identifier:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral

IdentifierChars:
JavaLetter {JavaLetterOrDigit}

JavaLetter:
any Unicode character that is a "Java letter"

JavaLetterOrDigit:
any Unicode character that is a "Java letter-or-digit"

Literal:
IntegerLiteral
FloatingPointLiteral
BooleanLiteral
CharacterLiteral
StringLiteral
NullLiteral

Type:
PrimitiveType
ReferenceType

PrimitiveType:
{Annotation} NumericType
{Annotation} |boolean|

NumericType:
IntegralType
FloatingPointType

IntegralType:
|byte| |short| |int| |long| |char|

FloatingPointType:
|float| |double|

ReferenceType:
ClassOrInterfaceType
TypeVariable
ArrayType

ClassOrInterfaceType:
ClassType
InterfaceType

ClassType:
{Annotation} Identifier [TypeArguments]
ClassOrInterfaceType |.| {Annotation} Identifier [TypeArguments]

InterfaceType:
ClassType

TypeVariable:
{Annotation} Identifier

ArrayType:
PrimitiveType Dims
ClassOrInterfaceType Dims
TypeVariable Dims

Dims:
{Annotation} |[| |]| {{Annotation} |[| |]|}

TypeParameter:
{TypeParameterModifier} Identifier [TypeBound]

TypeBound:
|extends| TypeVariable
|extends| ClassOrInterfaceType {AdditionalBound}

AdditionalBound:
|&| InterfaceType

TypeArguments:
|<| TypeArgumentList |>|

TypeArgumentList:
TypeArgument {|,| TypeArgument}

TypeArgument:
ReferenceType
Wildcard

Wildcard:
{Annotation} |?| [WildcardBounds]

WildcardBounds:
|extends| ReferenceType
|super| ReferenceType

CompilationUnit:
[PackageDeclaration] {ImportDeclaration} {TypeDeclaration}

PackageDeclaration:
{PackageModifier} |package| Identifier {|.| Identifier} |;|

PackageModifier:
Annotation

ImportDeclaration:
SingleTypeImportDeclaration
TypeImportOnDemandDeclaration
SingleStaticImportDeclaration
StaticImportOnDemandDeclaration

SingleTypeImportDeclaration:
|import| TypeName |;|

TypeImportOnDemandDeclaration:
|import| PackageOrTypeName |.| |*| |;|

SingleStaticImportDeclaration:
|import| |static| TypeName |.| Identifier |;|

StaticImportOnDemandDeclaration:
|import| |static| TypeName |.| |*| |;|

TypeDeclaration:
ClassDeclaration
InterfaceDeclaration
|;|

ClassDeclaration:
NormalClassDeclaration
EnumDeclaration

NormalClassDeclaration:
{ClassModifier} |class| Identifier [TypeParameters] [Superclass]
[Superinterfaces] ClassBody

ClassModifier:
Annotation |public| |protected| |private|
|abstract| |static| |final| |strictfp|

TypeParameters:
|<| TypeParameterList |>|

TypeParameterList:
TypeParameter {|,| TypeParameter}

Superclass:
|extends| ClassType

Superinterfaces:
|implements| InterfaceTypeList

InterfaceTypeList:
InterfaceType {|,| InterfaceType}

ClassBody:
|{| {ClassBodyDeclaration} |}|

ClassBodyDeclaration:
ClassMemberDeclaration
InstanceInitializer
StaticInitializer
ConstructorDeclaration

ClassMemberDeclaration:
FieldDeclaration
MethodDeclaration
ClassDeclaration
InterfaceDeclaration
|;|

FieldDeclaration:
{FieldModifier} UnannType VariableDeclaratorList |;|

FieldModifier:
Annotation |public| |protected| |private|
|static| |final| |transient| |volatile|

VariableDeclaratorList:
VariableDeclarator {|,| VariableDeclarator}

VariableDeclarator:
VariableDeclaratorId [|=| VariableInitializer]

VariableDeclaratorId:
Identifier [Dims]

VariableInitializer:
Expression
ArrayInitializer

UnannType:
UnannPrimitiveType
UnannReferenceType

UnannPrimitiveType:
NumericType
|boolean|

UnannReferenceType:
UnannClassOrInterfaceType
UnannTypeVariable
UnannArrayType

UnannClassOrInterfaceType:
UnannClassType
UnannInterfaceType

UnannClassType:
Identifier [TypeArguments]

UnannClassOrInterfaceType |.| {Annotation} Identifier [TypeArguments]

UnannInterfaceType:
UnannClassType

UnannTypeVariable:
Identifier

UnannArrayType:
UnannPrimitiveType Dims
UnannClassOrInterfaceType Dims
UnannTypeVariable Dims

MethodDeclaration:
{MethodModifier} MethodHeader MethodBody

MethodModifier:
Annotation |public| |protected| |private|
|abstract| |static| |final| |synchronized| |native| |strictfp|

MethodHeader:
Result MethodDeclarator [Throws]
TypeParameters {Annotation} Result MethodDeclarator [Throws]

Result:
UnannType
|void|

MethodDeclarator:
Identifier |(| [FormalParameterList] |)| [Dims]

FormalParameterList:
FormalParameters |,| LastFormalParameter
LastFormalParameter

FormalParameters:
FormalParameter {|,| FormalParameter}
ReceiverParameter {|,| FormalParameter}

FormalParameter:
{VariableModifier} UnannType VariableDeclaratorId

VariableModifier:
Annotation |final|

LastFormalParameter:
{VariableModifier} UnannType {Annotation} |...| VariableDeclaratorId
FormalParameter

ReceiverParameter:
{Annotation} UnannType [Identifier |.|] |this|

Throws:
|throws| ExceptionTypeList

ExceptionTypeList:
ExceptionType {|,| ExceptionType}

ExceptionType:
ClassType
TypeVariable

MethodBody:
Block
|;|

InstanceInitializer:
Block

StaticInitializer:
|static| Block

ConstructorDeclaration:
{ConstructorModifier} ConstructorDeclarator [Throws] ConstructorBody

ConstructorModifier:
Annotation |public| |protected| |private|

ConstructorDeclarator:
[TypeParameters] SimpleTypeName |(| [FormalParameterList] |)|

ConstructorBody:
|{| [ExplicitConstructorInvocation] [BlockStatements] |}|

ExplicitConstructorInvocation:
[TypeArguments] |this| |(| [ArgumentList] |)| |;|
[TypeArguments] |super| |(| [ArgumentList] |)| |;|
ExpressionName |.| [TypeArguments] |super| |(| [ArgumentList] |)| |;|
Primary |.| [TypeArguments] |super| |(| [ArgumentList] |)| |;|

EnumDeclaration:
{ClassModifier} |enum| Identifier [Superinterfaces] EnumBody

EnumBody:
|{| [EnumConstantList] [|,|] [EnumBodyDeclarations] |}|

EnumConstantList:
EnumConstant {|,| EnumConstant}

EnumConstant:
{EnumConstantModifier} Identifier [|(| [ArgumentList] |)|] [ClassBody]

EnumConstantModifier:
Annotation

EnumBodyDeclarations:
|;| {ClassBodyDeclaration}

InterfaceDeclaration:
NormalInterfaceDeclaration
AnnotationTypeDeclaration

NormalInterfaceDeclaration:
{InterfaceModifier} |interface| Identifier [TypeParameters]
[ExtendsInterfaces] InterfaceBody

InterfaceModifier:
Annotation |public| |protected| |private|
|abstract| |static| |strictfp|

ExtendsInterfaces:
|extends| InterfaceTypeList

InterfaceBody:
|{| {InterfaceMemberDeclaration} |}|

InterfaceMemberDeclaration:
ConstantDeclaration
InterfaceMethodDeclaration
ClassDeclaration
InterfaceDeclaration
|;|

ConstantDeclaration:
{ConstantModifier} UnannType VariableDeclaratorList |;|

ConstantModifier:
Annotation |public|
|static| |final|

InterfaceMethodDeclaration:
{InterfaceMethodModifier} MethodHeader MethodBody

InterfaceMethodModifier:
Annotation |public|
|abstract| |default| |static| |strictfp|

AnnotationTypeDeclaration:
{InterfaceModifier} |@| |interface| Identifier AnnotationTypeBody

AnnotationTypeBody:
|{| {AnnotationTypeMemberDeclaration} |}|

AnnotationTypeMemberDeclaration:
AnnotationTypeElementDeclaration
ConstantDeclaration
ClassDeclaration
InterfaceDeclaration
|;|

AnnotationTypeElementDeclaration:
{AnnotationTypeElementModifier} UnannType Identifier |(| |)| [Dims]
[DefaultValue] |;|

AnnotationTypeElementModifier:
Annotation |public|
|abstract|

DefaultValue:
|default| ElementValue

Annotation:
NormalAnnotation
MarkerAnnotation
SingleElementAnnotation

NormalAnnotation:
|@| TypeName |(| [ElementValuePairList] |)|

ElementValuePairList:
ElementValuePair {|,| ElementValuePair}

ElementValuePair:
Identifier |=| ElementValue

ElementValue:
ConditionalExpression
ElementValueArrayInitializer
Annotation

ElementValueArrayInitializer:
|{| [ElementValueList] [|,|] |}|

ElementValueList:
ElementValue {|,| ElementValue}

MarkerAnnotation:
|@| TypeName

SingleElementAnnotation:
|@| TypeName |(| ElementValue |)|

ArrayInitializer:
|{| [VariableInitializerList] [|,|] |}|

VariableInitializerList:
VariableInitializer {|,| VariableInitializer}

Block:
|{| [BlockStatements] |}|

BlockStatements:
BlockStatement {BlockStatement}

BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement

LocalVariableDeclarationStatement:
LocalVariableDeclaration |;|

LocalVariableDeclaration:
{VariableModifier} UnannType VariableDeclaratorList

Statement:
StatementWithoutTrailingSubstatement
LabeledStatement
IfThenStatement
IfThenElseStatement
WhileStatement
ForStatement

StatementNoShortIf:
StatementWithoutTrailingSubstatement
LabeledStatementNoShortIf
IfThenElseStatementNoShortIf
WhileStatementNoShortIf
ForStatementNoShortIf

StatementWithoutTrailingSubstatement:
Block
EmptyStatement
ExpressionStatement
AssertStatement
SwitchStatement
DoStatement
BreakStatement
ContinueStatement
ReturnStatement
SynchronizedStatement
ThrowStatement
TryStatement

EmptyStatement:
|;|

LabeledStatement:
Identifier |:| Statement

LabeledStatementNoShortIf:
Identifier |:| StatementNoShortIf

ExpressionStatement:
StatementExpression |;|

StatementExpression:
Assignment
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression

IfThenStatement:
|if| |(| Expression |)| Statement

IfThenElseStatement:
|if| |(| Expression |)| StatementNoShortIf |else| Statement

IfThenElseStatementNoShortIf:
|if| |(| Expression |)| StatementNoShortIf |else| StatementNoShortIf

AssertStatement:
|assert| Expression |;|
|assert| Expression |:| Expression |;|

SwitchStatement:
|switch| |(| Expression |)| SwitchBlock

SwitchBlock:
|{| {SwitchBlockStatementGroup} {SwitchLabel} |}|

SwitchBlockStatementGroup:
SwitchLabels BlockStatements

SwitchLabels:
SwitchLabel {SwitchLabel}

SwitchLabel:
|case| ConstantExpression |:|
|case| EnumConstantName |:|
|default| |:|

EnumConstantName:
Identifier

WhileStatement:
|while| |(| Expression |)| Statement

WhileStatementNoShortIf:
|while| |(| Expression |)| StatementNoShortIf

DoStatement:
|do| Statement |while| |(| Expression |)| |;|

ForStatement:
BasicForStatement
EnhancedForStatement

ForStatementNoShortIf:
BasicForStatementNoShortIf
EnhancedForStatementNoShortIf

BasicForStatement:
|for| |(| [ForInit] |;| [Expression] |;| [ForUpdate] |)| Statement

BasicForStatementNoShortIf:
|for| |(| [ForInit] |;| [Expression] |;| [ForUpdate] |)| StatementNoShortIf

ForInit:
StatementExpressionList
LocalVariableDeclaration

ForUpdate:
StatementExpressionList

StatementExpressionList:
StatementExpression {|,| StatementExpression}

EnhancedForStatement:
|for| |(| {VariableModifier} UnannType VariableDeclaratorId |:|
Expression |)| Statement

EnhancedForStatementNoShortIf:
|for| |(| {VariableModifier} UnannType VariableDeclaratorId |:|
Expression |)| StatementNoShortIf

BreakStatement:
|break| [Identifier] |;|

ContinueStatement:
|continue| [Identifier] |;|

ReturnStatement:
|return| [Expression] |;|

ThrowStatement:
|throw| Expression |;|

SynchronizedStatement:
|synchronized| |(| Expression |)| Block

TryStatement:
|try| Block Catches
|try| Block [Catches] Finally
TryWithResourcesStatement

Catches:
CatchClause {CatchClause}

CatchClause:
|catch| |(| CatchFormalParameter |)| Block

CatchFormalParameter:
{VariableModifier} CatchType VariableDeclaratorId

CatchType:
UnannClassType {||| ClassType}

Finally:
|finally| Block

TryWithResourcesStatement:
|try| ResourceSpecification Block [Catches] [Finally]

ResourceSpecification:
|(| ResourceList [|;|] |)|

ResourceList:
Resource {|;| Resource}

Resource:
{VariableModifier} UnannType VariableDeclaratorId |=| Expression

Primary:
PrimaryNoNewArray
ArrayCreationExpression

PrimaryNoNewArray:
Literal
TypeName {|[| |]|} |.| |class|
|void| |.| |class|
|this|
TypeName |.| |this|
|(| Expression |)|
ClassInstanceCreationExpression
FieldAccess
ArrayAccess
MethodInvocation
MethodReference

ClassInstanceCreationExpression:
|new| [TypeArguments] {Annotation} Identifier [TypeArgumentsOrDiamond]
|(| [ArgumentList] |)| [ClassBody]
ExpressionName |.| |new| [TypeArguments] {Annotation} Identifier
[TypeArgumentsOrDiamond] |(| [ArgumentList] |)| [ClassBody]
Primary |.| |new| [TypeArguments] {Annotation} Identifier
[TypeArgumentsOrDiamond] |(| [ArgumentList] |)| [ClassBody]

TypeArgumentsOrDiamond:
TypeArguments
|<>|

FieldAccess:
Primary |.| Identifier
|super| |.| Identifier
TypeName |.| |super| |.| Identifier

ArrayAccess:
ExpressionName |[| Expression |]|
PrimaryNoNewArray |[| Expression |]|

MethodInvocation:
MethodName |(| [ArgumentList] |)|
TypeName |.| [TypeArguments] Identifier |(| [ArgumentList] |)|
ExpressionName |.| [TypeArguments] Identifier |(| [ArgumentList] |)|
Primary |.| [TypeArguments] Identifier |(| [ArgumentList] |)|
|super| |.| [TypeArguments] Identifier |(| [ArgumentList] |)|
TypeName |.| |super| |.| [TypeArguments] Identifier |(| [ArgumentList] |)|

ArgumentList:
Expression {|,| Expression}

MethodReference:
ExpressionName |::| [TypeArguments] Identifier
ReferenceType |::| [TypeArguments] Identifier
Primary |::| [TypeArguments] Identifier
|super| |::| [TypeArguments] Identifier
TypeName |.| |super| |::| [TypeArguments] Identifier
ClassType |::| [TypeArguments] |new|
ArrayType |::| |new|

ArrayCreationExpression:
|new| PrimitiveType DimExprs [Dims]
|new| ClassOrInterfaceType DimExprs [Dims]
|new| PrimitiveType Dims ArrayInitializer
|new| ClassOrInterfaceType Dims ArrayInitializer

DimExprs:
DimExpr {DimExpr}

DimExpr:
{Annotation} |[| Expression |]|

ConstantExpression:
Expression

Expression:
LambdaExpression
AssignmentExpression

LambdaExpression:
LambdaParameters |->| LambdaBody

LambdaParameters:
Identifier
|(| [FormalParameterList] |)|
|(| InferredFormalParameterList |)|

InferredFormalParameterList:
Identifier {|,| Identifier}

LambdaBody:
Expression
Block

AssignmentExpression:
ConditionalExpression
Assignment

Assignment:
LeftHandSide AssignmentOperator Expression

LeftHandSide:
ExpressionName
FieldAccess
ArrayAccess

AssignmentOperator:
|=| |*=| |/=| |%=| |+=| |-=| |<<=| |>>=| |>>>=| |&=| |^=| ||=|

ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression |?| Expression |:| ConditionalExpression

ConditionalOrExpression:
ConditionalAndExpression
ConditionalOrExpression |||| ConditionalAndExpression

ConditionalAndExpression:
InclusiveOrExpression
ConditionalAndExpression |&&| InclusiveOrExpression

InclusiveOrExpression:
ExclusiveOrExpression
InclusiveOrExpression ||| ExclusiveOrExpression

ExclusiveOrExpression:
AndExpression
ExclusiveOrExpression |^| AndExpression

AndExpression:
EqualityExpression
AndExpression |&| EqualityExpression

EqualityExpression:
RelationalExpression
EqualityExpression |==| RelationalExpression
EqualityExpression |!=| RelationalExpression

RelationalExpression:
ShiftExpression
RelationalExpression |<| ShiftExpression
RelationalExpression |>| ShiftExpression
RelationalExpression |<=| ShiftExpression
RelationalExpression |>=| ShiftExpression
RelationalExpression |instanceof| ReferenceType

ShiftExpression:
AdditiveExpression
ShiftExpression |<<| AdditiveExpression
ShiftExpression |>>| AdditiveExpression
ShiftExpression |>>>| AdditiveExpression

AdditiveExpression:
MultiplicativeExpression
AdditiveExpression |+| MultiplicativeExpression
AdditiveExpression |-| MultiplicativeExpression

MultiplicativeExpression:
UnaryExpression
MultiplicativeExpression |*| UnaryExpression
MultiplicativeExpression |/| UnaryExpression
MultiplicativeExpression |%| UnaryExpression

UnaryExpression:
PreIncrementExpression
PreDecrementExpression
|+| UnaryExpression
|-| UnaryExpression
UnaryExpressionNotPlusMinus

PreIncrementExpression:
|++| UnaryExpression

PreDecrementExpression:
|--| UnaryExpression

UnaryExpressionNotPlusMinus:
PostfixExpression
|~| UnaryExpression
|!| UnaryExpression
CastExpression

PostfixExpression:
Primary
ExpressionName
PostIncrementExpression
PostDecrementExpression

PostIncrementExpression:
PostfixExpression |++|

PostDecrementExpression:
PostfixExpression |--|

CastExpression:
|(| PrimitiveType |)| UnaryExpression
|(| ReferenceType {AdditionalBound} |)| UnaryExpressionNotPlusMinus
|(| ReferenceType {AdditionalBound} |)| LambdaExpression
 
R

Roedy Green

Not parser generator but some issues to be aware of.
<http://openjdk.java.net/projects/compiler-grammar/>

I don't a full language parser because it would fail on fine points of
grammar unrelated to tidying the order of methods. It would also need
eternal maintenance as new esoteric features are added.

I wrote a finite state machine for parsing Java fragments for
colourising. It has the advantage of surviving fragments or
grammatical errors. I might do it that way or try ANTLR/JavaCC to
invent a sort "birdseye" grammar of Java that should stable. It would
have a generic code element that must have balanced {} inside
excluding "..." ' ' and comments. I don't care what is inside a method
body, so long as I am sure I know where the method ends.


One of my big complaints with java is you can't tell where something
ends without a detailed analysis of every {} inside. The eye cannot do
that. You have to use a tool to do it that creates indentation which
the eye can understand. But often the two are out of sync.

I hope some day the IDE will mark the ends of ifs, loops, classes with
some subtle but distinct visual clue in addition to indentation.
 
S

Silvio

What is considered the best parser nowadays that generates the parser
in Java source code?

What I need in an abbreviated Java parser just to cut the program into
chunks, each class within that each declaration and method.

I have already written the parsing that takes it from there.

The idea is to rearrange your code in a defined canonical order,
e.g. statics before instance primitives before references, char before
int...

If I were designing Java, I would have put a keyword on the front of
each declaration e.g. dcl, and each method "method".

This would make parsing simpler and faster. It would also make
navigating with a simple search string easier. IF the keyword were
shown in special colour, it would make it much easier by eye to detect
method starts.

The fact that a no such keywords exist does not make parsing slower by
definition. In the Java case it unlikely that such keywords would make
parsing faster. The language grammar defines how fast a parser can be.
Although the Java grammar is not strictly LALR(x) Java can be parsed
pretty left-to-right with the use of some simple tweaks and assumptions
to prevent expensive things like backtracking.

Now if you are talking about a much simpler parser that does shallow
parsing on basic text patterns only to find things like class names or
method names then the story changes a lot.
 
R

Roedy Green

The fact that a no such keywords exist does not make parsing slower by
definition. In the Java case it unlikely that such keywords would make
parsing faster. The language grammar defines how fast a parser can be.
Although the Java grammar is not strictly LALR(x) Java can be parsed
pretty left-to-right with the use of some simple tweaks and assumptions
to prevent expensive things like backtracking

Consider how far you have to parse into definition to tell if you have
a variable or a method definition.

An IDE could insert visible markers to mark the begins and end of
things. I must waste at least an hour a day trying to figure out which
{ } balances with what. It is not a task my eyes can do, especially
when the other half is offscreen.

Another solution would be a SCID which would not let you cut/copy
paste an unbalanced block of code. You would think of program as
composed on units -- like plumbing, not a stream of characters.
 
J

Joerg Meier

An IDE could insert visible markers to mark the begins and end of
things. I must waste at least an hour a day trying to figure out which
{ } balances with what. It is not a task my eyes can do, especially
when the other half is offscreen.

Eclipse already does that, and I suspect IDEA does as well. You click on
the opening brace and it will highlight the matching closing one as well as
have a line on the left to highlight the code inside the braces.

Liebe Gruesse,
Joerg
 
J

Jeff Higgins

Another solution would be a SCID which would not let you cut/copy
paste an unbalanced block of code. You would think of program as
composed on units -- like plumbing, not a stream of characters.

I hope I never run into an SCID in a text editing environment.
Maybe you're thinking of a graphical editing environment.
Come to think of it, maybe that's a solution to the current
@AnnotationOverloadSituation.
 
J

Joshua Cranmer ðŸ§

Consider how far you have to parse into definition to tell if you have
a variable or a method definition.

A hand-written recursive-descent parser (which is what almost all
production compilers use, since you can't get good error messages out of
an automatic parser generator and you don't want to write anything other
than recursive-descent by hand) can easily disambiguate it. You start by
parsing a specifier sequence, then a type, then the name, and you call
this set a declarator. The distinction between a method and a variable
is that a method is immediately followed by a ( paren whereas a variable
can be followed by a ,, =, or ;.

[Java 1.0 is definitely LALR(1). Someone claims to have a Java 5 LALR(1)
grammar, and I think Java 7 is LALR(1) as well. Don't know about Java 8.
It also slightly depends on whether or not you consider, e.g.,
inappropriate specifiers to be syntactic or semantic issues.]
An IDE could insert visible markers to mark the begins and end of
things. I must waste at least an hour a day trying to figure out which
{ } balances with what. It is not a task my eyes can do, especially
when the other half is offscreen.

Another solution would be a SCID which would not let you cut/copy
paste an unbalanced block of code. You would think of program as
composed on units -- like plumbing, not a stream of characters.

Neither of these tasks require much parsing, just lexing and keeping
track of balanced [/</{/( tokens. Unlike C or C++, it's basically
illegal to construct program fragments that correspond to single AST
productions that have mismatched parentheses.
 
S

Simon Lewis

Roedy Green said:
Consider how far you have to parse into definition to tell if you have
a variable or a method definition.

An IDE could insert visible markers to mark the begins and end of
things. I must waste at least an hour a day trying to figure out which
{ } balances with what. It is not a task my eyes can do, especially
when the other half is offscreen.

Huh? Use expand/collapse then in any good editor. Its easy. Especially
with colour hiliting parenthesis matching.
Another solution would be a SCID which would not let you cut/copy
paste an unbalanced block of code. You would think of program as
composed on units -- like plumbing, not a stream of characters.

You mean like all programmers already do? And pretty much all editors
treat them?
 
A

Andreas Leitgeb

Joerg Meier said:
Eclipse already does that, and I suspect IDEA does as well. You click on
the opening brace and it will highlight the matching closing one as well as
have a line on the left to highlight the code inside the braces.

For the record, eclipse also has another brace/bracket/parens related
feature, where you can jump the cursor to the matching b/b/p.

(On my machine I remapped that feature to Ctrl-Shift-5 (as close as
possible to vi's '%'), and I don't remember the original shortcut.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top