VS code snippet substitution (transform) works with variables not placeholders - visual-studio-code

vs code supposedly is supports substation, i.e., transforms, in user-defined snippets. But its working for me only with (built-in) variables and not placeholders.
See the following snippet:
"substitution test" : {
"prefix" : "abc",
"body": [
"${TM_FILENAME}",
"${TM_FILENAME/^([^.]+)\\..+$/$1/}",
"${TM_FILENAME/^([^.]+)\\..+$/${1:/capitalize}/}",
"${TM_FILENAME/^([^.]+)\\..+$/${1:/upcase}/}",
"${2:showMeInAllCapsWhenReferenced}",
"${2/upcase}"
]
}
The output of lines 1-4 is as expected:
users.actions.ts
users
Users
USERS
In line 5 there is a placeholder and I reference it again in line 6. I want it to show both times, once as I type it, and again in all-caps. So e.g.:
fooFoo
FOOFOO
But the actual output is
showMeInAllCapsWhenReferenced
${2/upcase}
Is substitution/transformation of referenced placeholders (as I type) even possible?

Your last two lines should be:
"${2:showMeInAllCapsWhenReferenced}",
"${2/(.*)/${1:/upcase}/}"
After the final tab the transform is actually applied (so not technically "as you type" the placeholder replacement).
From placeholder transforms:
The inserted text is matched with the regular expression and the match
or matches - depending on the options - are replaced with the
specified replacement format text.
So you cannot just use :/upcase for example without the regex capture as you tried to do on line 5 - it can only transform a regex match.
Looking at the grammar section :
transform ::= '/' regex '/' (format | text)+ '/' options
format ::= '$' int | '${' int '}'
| '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'
| '${' int ':+' if '}'
| '${' int ':?' if ':' else '}'
| '${' int ':-' else '}' | '${' int ':' else '}'
we see that the :/upcase must follow a regex. (The "format", of which upcase is one, must follow a "regex" in a "transform".)

Related

Parse TSQL/Sybase *= conditional operator used to express outer join using ANTLR4

Sybase has that non-ANSI SQL conditional operator used to express outer join: *=.
It's being deprecated (http://dcx.sybase.com/1200/en/dbusage/apxa-transactsqlouter-joins-aspen.html).
As we are moving from Sybase ASE to MySQL I have started to use ANTLR4 to parse the Sybase SQL code to try to translate it into the MySQL code equivalent.
I have tried adding it to the TSqlParser.g4 grammar available here: https://github.com/antlr/grammars-v4/tree/master/sql/tsql. See '*' '=' at the end of the line below but it doesn't work
// https://msdn.microsoft.com/en-us/library/ms188074.aspx
// Spaces are allowed for comparison operators.
comparison_operator
: '=' | '>' | '<' | '<' '=' | '>' '=' | '<' '>' | '!' '=' | '!' '>' | '!' '<' | '*' '='
;
I tried a few things to make it work like escaping \* and removing the *= assignment_operator but nothing works. It's probably a dumb question since I'm new to ANTLR. :-(
Please help.
The input *= is being tokenised as a MULT_ASSIGN by the lexer. You defined it as two separate tokens: '*' '=', which is not the same as '*='.
If you parse following the input with your grammar:
SELECT Q
FROM T
WHERE ID * = 42;
it will go fine, but to parse this properly:
SELECT Q
FROM T
WHERE ID *= 42;
you need to do it like this:
comparison_operator
: ... | '*='
;
and to support both, do this:
comparison_operator
: ... | '*' '=' | '*='
;

How to implement EOF in Antlr4 Grammar

I have a grammar that I am using for TSQL-esque language validation. Currently the grammar rules will work with a statement such as SUM(column1) + SUM(column2).
I would like the parser to throw an error if it was given something like
SUM(column1) SUM(column2). Notice the lack of an operator between the two SUMs. Right now, if I run this statement through the parser it does not error out. Instead it will return the first part of the statement, SUM(column1) and completely disregard the rest of the statement.
Upon research, I believe the answer to my problem is adding a EOF to my grammar. I have tried to implement this in several ways but it has not made any difference to the parsing.
This is the best way I can think to implement it in my grammar file, in the argument_list:
grammar DataAnalysis;
expression : literal #literalAtomExp
| FUNCTION=ID '(' argument_list ')' #functionExp
| INLINE_FUNCTION '(' argument_list ')' #inlineFunctionExp
| '(' expression ')' #parenthesisExp
| expression (ASTERISK|SLASH) expression #mulDivExp
| expression (PLUS|MINUS) expression #addSubExp
| <assoc=right> expression '^' expression #powerExp
| QUOTEDTEXT #stringExp
;
argument_list : expression (',' expression)* EOF //implemented here
;
literal : (TABLE_NAME=ID '.')? COLUMN_NAME=ID
| VALUE=NUMBER
;
fragment NAME : [a-zA-Z0-9_] ;
fragment LETTER : [a-zA-Z] ;
fragment DIGIT : [0-9] ;
ASTERISK : '*' ;
SLASH : '/' ;
PLUS : '+' ;
MINUS : '-' ;
INLINE_FUNCTION : 'YEAR'
| 'MONTH'
| 'DAY'
;
NUMBER : ('-')? DIGIT+ ('.' DIGIT+)? ;
ID : LETTER (NAME+) ;
QUOTEDTEXT : '"' .*? '"' ;
WHITESPACE : ' ' -> channel(HIDDEN);
Even like this the parsing doesn't pick up on the issue and returns only the first part of the query.
To summarize, when I feed the parser SUM(column1) SUM(column2) I would like it to return an error because it doesn't have any associated rule for that case.
Don't know what I am missing. Thanks for any direction.
Augment the grammar with "expr_prime : expression EOF;", and remove the EOF from the argument_list rule. Start parsing with expr_prime().

Visual studio code user snippets capitalize not working properly

I wrote such code
"State": {
"prefix": "state",
"body": [
"const [$1, set${1:/capitalize}] = useState($2);"
],
"description": "Adds state"
},
I expect that the result will be (if I enter test in $1) like this:
const [test, setTest] = useState($2);
But I get such result:
const [/capitalize, set/capitalize] = useState();
In official docs I found such rule: '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'.
Could you please tell what I am doing wrong?
You can use below snippet for the requested output:
const [$1, set${1/(.*)/${1:/capitalize}/}] = useState($2);
Output will be (in case I enter $1 as test):
const [test, setTest] = useState();
Lets look at why your version ${1:/capitalize} doesn't work:
Here is a portion of the snippet grammar you cited from https://code.visualstudio.com/docs/editor/userdefinedsnippets
tabstop ::= '$' int
| '${' int '}'
| '${' int transform '}'
-snip-
transform ::= '/' regex '/' (format | text)+ '/' options
format ::= '$' int | '${' int '}'
| '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'
So initially it looks like ${1:/capitalize} is correct, just looking at the last line of the grammar above it seems
${' int ':' '/capitalize'
is a valid option. But you have to track through the grammar to use it properly. The format syntax can only be used in a transform. We see this in:
transform ::= '/' regex '/' (format | text)+ '/' options
So right there your version does not include a transform. You do not have the necessary regex preceder. So those '/upcase' | '/downcase' | '/capitalize' options can only be used as part of a transform with a regex (although you can have an empty regex but that doesn't help you and you still need to have the regex entry point anyhow).
Here is the general form of a transform:
${someInt/regex captures here/do something with the captures here, like ${1:/capitalize} /}
Note that the first $someInt is a tabstop - it could be $1 for example, but the second $1 (with the capitalize) is NOT a tabstop but a reference to the first capture group from the preceding regex. So a transform can only transform something that has been captured by a regex.
The grammar requires that the format option be part of a transform, and a transform requires a regex and $n's in the format part refer to capture groups and not tabstop variables.
I hope this all makes sense.

Error highlights in every line when grammar breaks somewhere in Xtext editor

public
class FirstExample { // Here in this example we define some properties in our class
WRITE // This WRITE command follows a rule type defined in my grammar
Hello World
private
String firstTitle ;
private
String secondTitle ;
private
Integer firstAmount ;
private
Integer secondAmount ;
SET
firstTitle = "Ramesh"
SET
secondTitle = "Suresh"
SET
firstAmount = 100
SET
secondAmount = 200
When I change the command 'WRITE' to 'WRITEE' then error highlights in every line.
In eclipse java editor when we write a wrong syntax then error shows on that line only.
I am searching solution for this issue for past 2 days but not able to find the solution.
Kindly help me.I am not able to upload the picture due to some 10 reputation message comes while posting the question..
I am sending the grammar.Kindly check it once.
grammar org.xtext.example.mydsl.MyPoc with org.eclipse.xtext.common.Terminals hidden (GUESS_COMMENT,WS)
generate myPoc "http://www.xtext.org/example/mydsl/MyPoc"
Domainmodel:
(elements+=Type)*;
Type:Class;
// This is the starting point of the grammar
Class:
(packageList+=packageList)*
(packageList+=Import)*
(directives+=Directives) 'class' name=ID ('extends' superType=[Class])? '{'
(greetings+=Greeting)*
(features+=Feature)*
setValues+=SetValues*
operations+=Operation*
functionCall+=ArithmeticOperation*
directives+=Directive*
allMethod+=AllMethod*
allMethodInClass+=AllMethodInClass*
samples+=Samples*
'}';
//Package list consist of all the packages we want to include in our class
packageList:
('package' name=ID) ('.'?) (classes+=[Class])?;
//Import list consist of all the packages we want to include in our class
Import:
'import' importedNamespace=QualifiedNameWithWildcard;
QualifiedNameWithWildcard:
'QualifiedName' '.*'?;
Greeting:
(directives+=Directives)'Hello World'';'
(directives+=Directives)?'bye'?';'
(directives+=Directives)?';'
;
// Features defines the properties of that class
// In our grammar by default we make the property private
// our grammar takes two types of DataType String or Integer
// Name of the property given as per rule ID defined in Terminal file
Feature:
(directives+=Directives)* type=DATA_TYPE name=ID ';';
// In SetValues we initialize the properties by using SET directive
SetValues:
(directives+=Directives) name=ID ('='?) (INT | STRING)';';
//In Operation we define the function,arguments with there Data Type
Operation:
'Do' name=ID ('(' types+=DATA_TYPE args+=ID (',' types+=DATA_TYPE
args+=ID)* ')')?';';
//In Arithmetic Operation we call the function using $ passing the parameters
ArithmeticOperation:
(directives+=Directives)? name=ID '=' (directives+=Directives)? ('$')? types+=[Operation] ('(' (args+=ID) ','
(args+=ID)* ')')?';';
//In Samples we use Do While loop and inside that loop we use if else block
Samples:
name=ID (directives+=Directives) ('!,' STRING)? loopConstruct+=LoopConstruct* operations+=Operation*;
// In AllMethod we can call any method by using class name with '.' operator
AllMethod:
(classes+=[Class]) "." types+=[Operation] ('(' (args+=INT | ID) ',' (args+=INT | ID)* ');')?;
// In AllMethodInClass we can see all methods present in that class
AllMethodInClass:
types+=[Operation] ('(' (args+=INT | ID) ',' (args+=INT | ID)* ');')?;
//In LoopConstruct we define how we can use Do while loop with directive types given below
LoopConstruct:
(directives+=Directives) ("{"
(directives+=Directives ('!,' STRING))*
(directives+=Directive)*
"}")
(directives+=Directives) ("{"
(directives+=Directives ('!,' STRING))*
(directives+=Directive)*
"}")?
(directives+=Directives)?;
Directive:
(directives+=Directives) ('(' name=ID LOOP_CODITION_CHECK name=ID ')')?
'{' (directives+=Directives ('!,' STRING)?)* '}';
Directives:
name=DirectiveType;
DirectiveType:
{DirectiveType} value=DIRECTIVES_TYPE;
// From here all are rules which shows that what we can use in our grammar
terminal DATA_TYPE:
('Integer' | 'String');
// These are some directives
// WRITE is following this rule
terminal DIRECTIVES_TYPE:
('SET' | 'WRITE' | 'READ' | 'QUIT' | 'If' | 'ElseIf' | 'Else' | 'EndIf' | 'Do' | 'while' | 'private' | 'public' | 'do');
terminal LOOP_CODITION_CHECK:
('=' | '>' | '<' | '!')+;
terminal GUESS_COMMENT : '//' !('\n'|'\r')* ('\r'? '\n');
I want to make it clear that WRITE is not only the issue.The line from where grammar breaks it shows error on the remaining lines comes after that line.
After changing my class rule with your code it gives lots of warning.I am sending the warning messages.
warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:416:2: Decision can match input such as "RULE_ID {RULE_ID..RULE_DATA_TYPE, RULE_DIRECTIVES_TYPE, 'Do'}" using multiple alternatives: 8, 9
As a result, alternative(s) 9 were disabled for that input
error(201): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:416:2: The following alternatives can never be matched: 9
warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:1166:1: Decision can match input such as "RULE_DIRECTIVES_TYPE '{' RULE_DIRECTIVES_TYPE '!,' RULE_STRING '}' RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:1184:1: Decision can match input such as "'Do' RULE_ID '(' RULE_DATA_TYPE RULE_ID ',' RULE_DATA_TYPE RULE_ID ')' ';'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyPoc.g:1546:3: Decision can match input such as "RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:568:1: Decision can match input such as "RULE_ID {RULE_ID, RULE_DATA_TYPE..RULE_DIRECTIVES_TYPE, '}', 'Do'..'('}" using multiple alternatives: 8, 9
As a result, alternative(s) 9 were disabled for that input
error(201): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:568:1: The following alternatives can never be matched: 9
warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:2810:42: Decision can match input such as "RULE_DIRECTIVES_TYPE '{' RULE_DIRECTIVES_TYPE '!,' RULE_STRING '}' RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:2838:39: Decision can match input such as "'Do' RULE_ID '(' RULE_DATA_TYPE RULE_ID ',' RULE_DATA_TYPE RULE_ID ')' ';'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
warning(200): ../org.xtext.example.myPoc.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyPoc.g:3561:1: Decision can match input such as "RULE_DIRECTIVES_TYPE" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
After the warning code gives an exception
GeneratorException: (Element: -UNKNOWN-; Reported by: Generator)
org.eclipse.emf.common.util.WrappedException: java.io.FileNotFoundException: ..\org.xtext.example.myPoc\src-gen\org\xtext\example\mydsl\parser\antlr\internal\InternalMyPocLexer.java (The system cannot find the file specified)
I have reduced my grammar and remove all the error and warnings from my code but the error highlighting in every line is still there.
Now my grammar is
grammar org.xtext.example.mydsl.MyPoc with org.eclipse.xtext.common.Terminals hidden (GUESS_COMMENT,WS)
generate myPoc "http://www.xtext.org/example/mydsl/MyPoc"
Domainmodel:
(elements+=Type)*;
Type:Class;
// This is the starting point of the grammar
Class:
(packageList+=packageList)*
(packageList+=Import)*
(directives+=Directives) 'class' name=ID ('extends' superType=[Class])? '{'
(greetings+=Greeting
|features+=Feature
|setValues+=SetValues)*
'}';
//Package list consist of all the packages we want to include in our class
packageList:
('package' name=ID) ('.'?) (classes+=[Class])?;
//Import list consist of all the packages we want to include in our class
Import:
'import' importedNamespace=QualifiedNameWithWildcard;
QualifiedNameWithWildcard:
'QualifiedName' '.*'?;
Greeting:
(directives+=Directives)'Hello World'';'
(directives+=Directives)?'bye'?';'
(directives+=Directives)?';'
;
// Features defines the properties of that class
// In our grammar by default we make the property private
// our grammar takes two types of DataType String or Integer
// Name of the property given as per rule ID defined in Terminal file
Feature:
(directives+=Directives)* type=DATA_TYPE name=ID ';';
// In SetValues we initialize the properties by using SET directive
SetValues:
(directives+=Directives) name=ID ('='?) (INT | STRING)';';
Directives:
name=DirectiveType;
DirectiveType:
{DirectiveType} value=DIRECTIVES_TYPE;
// From here all are rules which shows that what we can use in our grammar
terminal DATA_TYPE:
('Integer' | 'String');
// These are some directives used by us taken from there website
terminal DIRECTIVES_TYPE:
('SET' | 'WRITE' | 'READ' | 'QUIT' | 'If' | 'ElseIf' | 'Else' | 'EndIf' | 'Do' | 'while' | 'private' | 'public' | 'do');
terminal LOOP_CODITION_CHECK:
('=' | '>' | '<' | '!')+;
terminal GUESS_COMMENT : '//' !('\n'|'\r')* ('\r'? '\n');
And in eclipse xtext editor when I write private as privatee it shows error in every line.
My code is
public
class MyPoc {
private
String firstTitle ;
**privatee**
String title ;
private
String secondTitle ;
private
Integer firstAmount ;
private
Integer secondAmount ;
SET
firstTitle = "Ramesh";
SET
secondTitle = "Suresh";
SET
firstAmount = 100;
SET
secondAmount = 200;
}
Now I add some more grammar in my class attribute.The console shows no warning and no exception.But in eclipse editor again when we break grammar syntax it shows error in every line.
Class:
(packageList+=packageList)*
(packageList+=Import)*
(directives+=Directives) 'class' name=ID ('extends' superType=[Class])? LBRACKET
(directives+=Directives* (features+=Feature | setValues+=SetValues | operations+=Operation | functionCall+=ArithmeticOperation | allMethod+=AllMethod
| allMethodInClass+=AllMethodInClass | samples+=Samples) SEMICOLON)*
RBRACKET;
Kindly check it once and correct me if I am doing something wrong.
I have found that problem is not in the class part.The problem is in the parts where we define the rule in the grammar.
Like for ArithmeticOperation
ArithmeticOperation:
(directives+=Directives)? name=ID '=' (directives+=Directives)? ('$')? types+=[Operation] ('(' (args+=ID) ','
(args+=ID)* ')')?';';
Actually I have to write this code in eclipse.Here Concat is the opeartion name means method name.
SET Result = WRITE $ Concat (firstTitle , secondTitle)
Kindly correct me if I ma doing something wrong to achieve my target code.
Regards
Xtext error recovery system is not the same than Java Editor (JDT). Its behavior depends on how you write your rules.
Maybe your grammar is too much ambiguous and you should add a line termination symbol.
Also, you should read this article about error recovery with Xtext: Parser error recovery
Edit
Currently the class rule is very ambiguous with chaining rules with the same first token. The first thing you should do is to rewrite your class rule and remove all ambiguities.(warnings & erros when compiling grammar).
See the following example of class rule:
Class:
(packageList+=packageList)*
(packageList+=Import)*
(directives+=Directives) 'class' name=ID ('extends' superType=[Class])? '{'
(greetings+=Greeting | features+=Feature | setValues+=SetValues
| operations+=Operation | functionCall+=ArithmeticOperation
| directives+=Directive | allMethod+=AllMethod
| allMethodInClass+=AllMethodInClass | samples+=Samples)*
'}';
Edit 2
I made some refactorings to your grammar. And now it has the behavior you asked for.
Domainmodel:
(elements+=Type)*;
Type:Class;
// This is the starting point of the grammar
Class:
(packageList+=packageList)*
(packageList+=Import)*
(directives+=Directives) 'class' name=ID ('extends' superType=[Class])? LBRACKET
(directives+=Directives* (features+=Feature | setValues+=SetValues) SEMICOLON)*
RBRACKET;
terminal SEMICOLON:
';'
;
terminal LBRACKET:
'{'
;
terminal RBRACKET:
'}'
;
//Package list consist of all the packages we want to include in our class
packageList:
('package' name=ID) ('.'?) (classes+=[Class])?;
//Import list consist of all the packages we want to include in our class
Import:
'import' importedNamespace=QualifiedNameWithWildcard;
QualifiedNameWithWildcard:
'QualifiedName' '.*'?;
// Features defines the properties of that class
// In our grammar by default we make the property private
// our grammar takes two types of DataType String or Integer
// Name of the property given as per rule ID defined in Terminal file
Feature:
type=DATA_TYPE name=ID ;
// In SetValues we initialize the properties by using SET directive
SetValues:
name=ID ('='?) (INT | STRING);
Directives:
name=DirectiveType;
DirectiveType:
{DirectiveType} value=DIRECTIVES_TYPE;
// From here all are rules which shows that what we can use in our grammar
terminal DATA_TYPE:
('Integer' | 'String');
// These are some directives used by us taken from there website
terminal DIRECTIVES_TYPE:
('SET' | 'WRITE' | 'READ' | 'QUIT' | 'If' | 'ElseIf' | 'Else' | 'EndIf' | 'Do' | 'while' | 'private' | 'public' | 'do');
terminal LOOP_CODITION_CHECK:
('=' | '>' | '<' | '!')+;
terminal GUESS_COMMENT : '//' !('\n'|'\r')* ('\r'? '\n');
Details of what i changed:
- Removed (useless?) greeting rule.
- Made line/block separators terminals.
- Moved directive to parent rule.
Sample code for editor:
public
class MyPoc {
private
String firstTitle ;
privatee
String title ;
private
String secondTitle ;
private
Integer firstAmount ;
private
Integer secondAmount ;
SET
firstTitle = "Ramesh";
SET
secondTitle = "Suresh";
SET
firstAmount = 100;
SET
secondAmount = 200;
}

Parsing and converting 4Test to Perl

I want to convert 4Test scripts to Perl. I have been using the Parse::RecDescent in Perl, but am still overwhelmed at the task. Here is an example.
An example of 4Test is something like:
ParseSMSPlans (STRING sDir)
{
STRING sFile;
STRING sDirSMSPlan = sDir + "sms_plans\";
STRING sDirPlan = sDir + "plan\";
STRING sDirDeal = sDir + "deal\";
STRING sDirProduct = sDir + "product\";
STRING sLine, sType, sName;
HFILE hIn;
FILEINFO fiFile;
LIST OF FILEINFO lfInfo = SYS_GetDirContents (sDirSMSPlan);
...
}
...
This is my Parse::RecDescent grammar
my $grammar = q{
#-----------------identifiers and datatypes-------------------#
identifier : /[a-z]\w+/
binops : '+' | '-' | '/' | '*' | '%' | '**'
lbinops: '!' | '<' | '>' | '>='| '<='| '&&'| '||' | '=='
integer: /\d+/ {print "hello $item[-1]" if $::debugging;}
number : /(\d+|\d*\.\d+)/ {print "hello $item[-1]" if $::debugging;}
string : /"(([^"]*)(\\")?)*"/
operation : number binops number operation(s?)
datatype : /[a-zA-Z]\w*/
definition : datatype expression(s) #{print "hello $item[-1]" if $::debugging;}
|datatype expression(s) "=" expression(s) #{print "hello $item[-1] = $item[-2]" if $::debugging;}
statement : ifexp | elsexp | elseifexp |forexp | feachexp | whexp | swcexp
#------------------Expressed Values-----------------------------#
program : expression
expression : number {print $item[1] if $::debugging}
| integer
| assignment
| operation
| identifier binops expression
| number binops expression
#------------------Conditionals---------------------------------------#
ifexp : 'if' '(' expression(s) ')' '{' expression(s) '}' elsexp(?)
elsexp : 'else' '{' expression(s) '}'
elseifexp: 'else' 'if' '(' expression(s) ')' '{' expression(s) '}'
forexp : 'for' '(' expression ';' expression ';' expression ')' '{' expression(s) }'
| 'for' assignment 'to' number expression(s) | 'for' assignment 'to' number '{' expression(s) '}'
feachexp : 'for each' expression 'in' expression '{' expression(s) '}'
whexp : 'while' '(' expression ')' '{' expression(s) '}'
casest : 'case' expression(s /,/) ':'
swcexp : 'switch' identifier '{' casest(s) '}' expression(s) 'default'
assignment : identifier(s) '=' expression
};
So, I'm looking at adding "$" to every variable name, and chopping
datatypes. For the most part my grammar works, though I have fully
tested it yet, but only because Parse::RecDescent has been a bit
tricky for me to understand and, I'm not really sure if it's the best
way to complete my task...or the fastest, for that matter.
My main concern is whether or not anyone feels that PRD can handle what
I'm asking it to do or will simple(complex) regex(s) suffice? I would
appreciate any help anyone could offer on this.
May I suggest that you simplify your 4Test scripts by replacing all operator expressions with subroutine calls. You would then still be able to run them as 4Test scripts and thus prove that they worked, but you would greatly simplify the parsing problem - operator expressions are much more difficult to parse than straight procedure calls. Taken to the limit, this process will produce 4Test scripts which can almost be run directly by Perl+some replacement routines for 4Test functions.