So, I'm trying to parse code containg switch statements like this
function (a : Boolean) equals (b : Boolean) : Boolean {
switch (a) {
case true:
switch (b) {
case true:
return (true);
case false:
return (false);
}
case false:
switch (b) {
case true:
return (false);
case false:
return (true);
}
}
};
with
switch
: "switch" expression "{" cases "}" {
Switch $2 $4
}
;
cases
: case cases {
($1 : $2)
}
| case {
[$1]
}
;
case
: "case" pattern ":" caseStatements {
Case $2 $4
}
;
caseStatements
: caseStatement ";" caseStatements {
($1 : $3)
}
| caseStatement {
[$1]
}
;
caseStatement
: assignment {
AssignmentCaseStatement $1
}
| return {
ReturnCaseStatement $1
}
| switch {
SwitchCaseStatement $1
}
;
but I keep getting:
certa: user error (../examples/Certa/BooleanLogic.certa:16: Parse error at token 'case')
when I run the generated parser. The strange thing here is that it fails on the second instance of the "case" keyword, but not the first. Why in the world would that be?
Shouldn't your non-recursive leg of caseStatements include a semi-colon?
i.e.
caseStatements
: caseStatement ";" caseStatements {
($1 : $3)
}
| caseStatement ";" {
[$1]
}
;
Related
I'm a total newbie and I'm looking for some advice.
how to make a condition in Groovy so that if the variable is a string, then one action is performed, and if the sheet is another
and just as it is necessary to do, if the variable is equal to zero, then nothing is transmitted
//aditionalArgs= "test1 = add1 , tets2= add2 "
aditionalArgs = ["test1=arg1", "test2=arg2"]
println(aditionalArgs.class)
def args = ""
if ((aditionalArgs != "class java.lang.String" ) || (aditionalArgs > 0)){
def list = aditionalArgs.replace("--build-arg", "").split(',')
list.each { val->
args += " --build-arg $val"
}
println(args.replace("",""))
}
if (aditionalArgs == "ArrayList" ){
def list = aditionalArgs("--build-arg", "").split('[' , ']')
list.each { val->
args += " --build-arg $val"
}
println(args.replace("",""))
}
else(aditionalArgs.length() > 0){
println "empty aditionalArgs"
}```
if (aditionalArgs instanceof String && aditionalArgs.length() > 0) {
...
} else if (aditionalArgs instanceof List && aditionalArgs.size() > 0) {
...
} else {
println "unsupported arg type '${aditionalArgs?.getClass()}' or value '${aditionalArgs}'"
}
Your code suggests that you rather want to use a switch op:
switch( aditionalArgs ){
case String:
// do stuff with String
break
case List:
// do stuff with (Array)List
break
case Number:
// do something with Number
break
default:
throw new Exception( 'I have no idea' )
}
More on the statement is in the docs
My goal is to generate parser that could handle following code with named function parameters and nested function calls
fnCallY(namedArgStr = "xxx", namedArgZ=fnCallZ(namedArg="www"))
G4 lang file:
val : type_string
| function_call
;
function_call : function_name=ID arguments='('argument? (',' argument)* ')';
argument : name=ID '=' value=val ;
ID : [a-zA-Z_][a-zA-Z0-9_]*;
type_string : LITERAL;
fragment ESCAPED_QUOTE : '\\"';
LITERAL : '"' ( ESCAPED_QUOTE | ~('\n'|'\r') )*? '"'
| '\'' ( ESCAPED_QUOTE | ~('\n'|'\r') )*? '\'';
#Override
public void exitFunction_call(Test.Function_callContext ctx) {
List<Test.ArgumentContext> argument = ctx.argument();
for (Test.ArgumentContext arg : argument) {
Token name = arg.name;
Test.ValContext value = arg.value;
if (value.type_literal() == null || value.function_call() == null) {
throw new RuntimeException("Could not parse argument value");
}
}
}
arg.name holds correct data, but i cannot make the parser to parse the part after =.
The parser is recognizing the argument values.
(It's really valuable to learn the grun command line utility as it can test the grammar and tree structure without involving any of your own code)
This condition would appear to be your problem:
if (value.type_literal() == null || value.function_call() == null)
One or the other will always be null, so this will fail.
if (value.type_literal() == null && value.function_call() == null)
is probably what you want.
I am stuck at one point as I am unable to test my grammar using Junit test cases. Below is my complete grammar.
ExpressionModel:
expression=Expression;
Expression:
Comparison;
Comparison returns Expression:
Primary ({Comparison.left=current} op=("=" | "!=" | ">=" | "<=" | ">" | "<")right=Primary)* ;
Primary returns Expression:
'(' Expression ')' |
{Not} "!" expression=Primary |
Atomic;
Atomic returns Expression:
{IntConstant} value=INT |
{StringConstant} value=STRING |
{BoolConstant} value=('true' | 'false') |
{VariableRef} variable=[ecore::EAttribute|QualifiedName];
QualifiedName:
ID ('.' ID)*;
If i test my code generator for this grammar by launching an eclipse instance, all i have to do is create an ".ecore" file in the src folder and another file for my grammar and i am easily able to access my variable created in ".ecore" file.
What i mean to say is after launching an eclipse instance, i created a "test.ecore" file having a class "vars" and an EAttribute "alpha" which is of EString type and i created another file "testModel.dsl" now i am easily able to access "vars.alpha" inside this file. Can anyone please help me how to perform same steps if i want to test my code generator without launching an eclipse instance. It would be of great help to me.
I am trying to test below test case-->
#RunWith(XtextRunner)
#InjectWith(ExtendedMyDslInjectorProvider)
class ExpressionDSLCompilationTest {
#Inject extension CompilationTestHelper
#Inject extension ParseHelper
#Inject extension ReflectExtensions
#Inject extension IQualifiedNameProvider
#Inject Provider<XtextResourceSet> resourceSetProvider
#Test
def void ReturnVariable() {
val fooPackage = EcoreFactory::eINSTANCE.createEPackage
fooPackage.name = "foo"
fooPackage.nsPrefix = "foo"
fooPackage.nsURI = "http://foo"
val fooClass = EcoreFactory::eINSTANCE.createEClass
fooClass.name = "vars"
fooPackage.EClassifiers.add(fooClass)
val fooattr = EcoreFactory::eINSTANCE.createEAttribute
fooattr.name = "alpha"
fooattr.EType = EcorePackage::eINSTANCE.EString
val resourceset = resourceSetProvider.get
val resource = resourceset.createResource(URI.createURI("hiTest.ecore"))
fooClass.EStructuralFeatures.add(attr)
resource.contents.add(fooPackage)
// val model = '''foo.vars.alpha'''.parse(resourceset)
'''foo.vars.alpha'''.compile [
getCompiledClass.newInstance => [
assertEquals(
"foo.vars.alpha",
it.invoke("generateCodeForExpression")
)
]
]
}
class ExtendedMyDslInjectorProvider extends ExpressionDSLInjectorProvider {
override internalCreateInjector() {
EcoreSupportStandaloneSetup.setup
return super.internalCreateInjector
}
}
I have already followed steps mentioned in https://www.eclipse.org/forums/index.php/t/1081785/
but this is of no use as it is giving me null pointer exception when i run my test case. Any help will be appreciated.
I am adding a piece of my code generator and highlighting the piece where it is giving error. Hope it will be enough.
class ExpressionDSLGenerator extends AbstractGenerator {
#Inject extension IQualifiedNameProvider
/*Generate Java Code with the name of java file as same as that of ".mexpression" file*/
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
var str = ""
for (e : resource.allContents.toIterable.filter(ExpressionModel)) {
str += e.checkCompileForFunctionsOrExpresssion
}
fsa.generateFile('''«resource.URI.lastSegment.substring(0,resource.URI.lastSegment.indexOf("."))».java''', str)
}
/*Generates the body of .Java File having class and single checkExpression
Method for Expressions and Functions Separately */
def String checkCompileForFunctionsOrExpresssion(ExpressionModel model) {
'''
public class «model.eResource.URI.lastSegment.substring(0,model.eResource.URI.lastSegment.indexOf("."))»{
public «getExpressionReturnType(model)» generateCodeForExpression() {
return «getExpressionReturnBody(model.expression)»;
}
}
'''
}
def getExpressionReturnType(ExpressionModel model) {
/*If expression is not a comparison and just a single variable or value, we must return value's data type*/
if (model.eContents.size < 2) {
model.expression.getValueReturnType
} /* Return boolean since it will be a comparison*/ else {
"boolean"
}
}
// Utility method to get return type of an expression
def getValueReturnType(Expression e) {
if (e.isInt) {
"int"
} else if (e.isString) {
"String"
} else if (e.isVariable) {
e.variableReturnsType
} else {
"boolean"
}
}
// Utility method to set return type on the basis of variable's return type
def getVariableReturnsType(Expression e) {
switch (e) {
VariableRef: {
<part giving error:-->e.variable.EType is coming to be null, hence null pointer exception>**e.variable.EType.name.equals("EString") ? "String" : e.variable.EType.name.equals(
"EInt") ? "int" : "boolean"**</part giving error>
}
}
}
// Utility method to get return body of an expression
def String getExpressionReturnBody(Expression e) {
switch (e) {
VariableRef: {
getVariableReturn(e.variable)
}
IntConstant: {
e.value.intConstantReturn
}
BoolConstant: {
e.value.booleanConstantReturn
}
StringConstant: {
e.value.stringConstantReturn
}
Not: {
e.expression.notExpressionReturn
}
Comparison: {
val left = e.left.getExpressionReturnBody as String
val right = e.right.getExpressionReturnBody as String
if (e.left.isString) {
getStringCompareBody(left, right, e.op)
} else if (e.left.isBoolean) {
getBoolCompareBody(left, right, e.op)
} else if (e.left.isVariable) {
getVariableReturnsBody(e.left, left, right, e.op)
} else {
getOthersCompareBody(left, right, e.op)
}
}
}
}
// return variable's full name
def getVariableReturn(EAttribute e) {
e.fullyQualifiedName + ""
}
// return integer value
def getIntConstantReturn(int value) {
value + ""
}
// return boolean value
def getBooleanConstantReturn(String value) {
Boolean::parseBoolean(value) + ""
}
// return string value
def getStringConstantReturn(String value) {
"\"" + value + "\""
}
// return not value of the given expression
def getNotExpressionReturn(Expression value) {
"!(" + value.getExpressionReturnBody + ")"
}
// Utility method to check if Expression is a String
def isString(Expression e) {
switch (e) {
StringConstant: {
true
}
default: {
false
}
}
}
// Utility method to check if Expression is a boolean
def isBoolean(Expression e) {
switch (e) {
BoolConstant: {
true
}
default: {
false
}
}
}
// Utility method to check if Expression is a variable
def isVariable(Expression e) {
switch (e) {
VariableRef: {
true
}
default: {
false
}
}
}
// return body of comparison expression for string
def getStringCompareBody(String left, String right, String op) {
switch (op) {
case '=': "(" + left + ".equals(" + right + "))"
case '!=': "!(" + left + ".equals(" + right + "))"
default: false + ""
}
}
// return body of comparison expression for boolean
def getBoolCompareBody(String left, String right, String op) {
switch (op) {
case '=': "(" + left + "==" + right + ")"
case '!=': "(" + left + "!=" + right + ")"
default: false + ""
}
}
// return body of comparison expression for other's
def getOthersCompareBody(String left, String right, String op) {
switch (op) {
case '<': "(" + left + "<" + right + ")"
case '>': "(" + left + ">" + right + ")"
case '>=': "(" + left + ">=" + right + ")"
case '<=': "(" + left + "<=" + right + ")"
case '=': "(" + left + "==" + right + ")"
case '!=': "!(" + left + "==" + right + ")"
default: false + ""
}
}
// body for variable type
def getVariableReturnsBody(Expression e, String left, String right, String operator) {
switch (e) {
VariableRef: {
e.variable.EType.name.equals("EString")
? getStringCompareBody(left, right, operator) : e.variable.EType.name.equals(
"EBoolean") ? getBoolCompareBody(left, right, operator) : getOthersCompareBody(left, right,
operator)
}
}
}
}
#Inject extension ValidationTestHelper h
...
val model = '''foo.vars.alpha'''.parse(resourceset)
model.assertNoErrors
which is the adaption of the forum snippet to your context works perfectly fine
if you want to use CompilationTestHelper then you have to customize it for the resourcetset to add the resource there
e.g.
val model = '''foo.vars.alpha'''.parse(resourceset)
model.assertNoErrors
compile(resourceset) [
getCompiledClass.newInstance => [
assertEquals(
"foo.vars.alpha",
it.invoke("generateCodeForExpression")
)
]
]
Okay... so I'm trying to make a dictionary using Crunch and Grep I've also tried using Perl instead.
crunch 8 12 1234567890 -d 2# | grep -v '\([0-9]\) .*\1.*\1.*\1.*' | grep 41106041
So, basically i want to filter all passwords which numbers appear 3 times
grep 41106041
Is just to test if the code works.. and it doesn't.
I've also tried some "C style" perl code as I'm still a newbie to perl:
#! /bin/perl
#lines=<STDIN>;
$c=0;
foreach $number(#lines)
{
$acum=undef;
$pos=0;
while($pos <= &countdig($number))
{
if ($acum=$digit)
{
$c=$c+1;
}
else
{
$c=0;
}
$acum=$digit;
}
if ($c=3)
{
print "$number"." ";
}
$c=0;
}
sub countdig
{
my($j)=0;
chomp(my(#n)=#_);
print "first dig $n[$j] \n";
while($_[0][$j]>=0 && $_[0][j]<=9)
{
$j+=1;
}
print "j total : $j \n";
$j;
}
Countdig is supposed to count the number of digits but thing is.. I can't access a scalar variable as a list.. so well if you guys could explain me how to make it work it would be very appreciated.
Your grep is failing because there is a stray space in your pattern, and you are searching for 4 identical digits (the one captured, plus three more by backreference).
$ printf '12345678\n41106041\n87654321\n' | grep -v '\(.\).*\1.*\1'
12345678
87654321
The problem is not being a newbie to Perl, cause it's easy to turn a C solution
// For each line
char *num = ...;
int digits[10];
for (int i=0; i<10; ++i) {
digits[i] = 0;
}
const char *p = num;
int triple = 0;
for (; *p && *p != '\n'; ++p) {
if (++digits[*p - '0'] == 3) {
triple = 1;
break;
}
}
if (triple) {
...
}
into a Perl solution
while (my $num = <>) {
chomp($num);
my #digits;
my $triple;
for my $digit (split //, $num) {
if (++$digits[$digit] == 3) {
$triple = 1;
last;
}
}
say $num if $triple;
}
Of course, a Perl programmer might very well use the same approach you used for grep.
while (<>) {
if (!/(.).*\1.*\1/) {
print;
}
}
echo 41106041 | grep -v '\([0-9]\).*\1.*\1.*
I have an awk file get_PV_sql_from_file.awk:
#! /bin/awk -f
/^CREATE.*VIEW.*PV_/
{
inside_create = 1; print "view found"
}
{
if(inside_create == 1)
{
print $0
}
}
/.*;$/
{
if(inside_create == 1){
inside_create = 0;
}
}
And when i run it:
awk -f get_PV_sql_from_file.awk test_PV_sql.txt
I have got "view found" phrase in each line:
view found
CREATE FORCE VIEW "POSC"."P3V_SEC_TREES_V" ("BSASC_ID", "BSASC_S", "LV0_K", "LV0_V", "LV1_K", "LV1_V", "LV2_K", "LV2_V", "LV3_K", "LV3_V", "LV4_K", "LV4_V", "LV5_K", "LV5_V") AS
view found
SELECT DISTINCT
view found
B1.BSASC_ID,
view found
B2.BSASC_S,
view found
R_SEC_TREES.LV0_K,
view found
R_SEC_TREES.LV0_V,
...
etc
But if i write each command in awk file on a single line:
#! /bin/awk -f
/^CREATE.*VIEW.*PV_/ { inside_create = 1; print "view found" }
{ if(inside_create == 1) { print $0 } }
/.*;$/ { if(inside_create == 1) { inside_create = 0; } }
It is works right:
view found
CREATE FORCE VIEW "POSC"."PV_SEC_MODULES_V" ("BSASC_ID", "MODULE", "ACT") AS
SELECT DISTINCT
B1.BSASC_ID BSASC_ID,
BSASC_PRIVILEGE.GDLN_OR_PRIV_ID MODULE,
BSASC_PRIVILEGE.R_BSASC_PRIV_KIND ACT
...
etc
Why is this happening? And where i made mistake?
You need to put the pattern and the opening brace that begins the action on the same line. Otherwise the pattern is treated as not having any action, so the default action, print the line, is performed. The action on the next line is then treated as having no pattern which means it matches every line. So write your AWK code like this:
/^CREATE.*VIEW.*PV_/ {
inside_create = 1; print "view found"
}
{
if(inside_create == 1)
{
print $0
}
}
/.*;$/ {
if(inside_create == 1) {
inside_create = 0;
}
}