How to set a variable inside `if` in Sass? - if-statement

Is it possibel to set a variable inside the parentheses of an if statement in Sass?
I've tried to:
#function test() {
#if ($variable: true) { <<<< line 67
#return $variable;
}
}
And it says: Undefined variable: "$variable". on line 67 at column 8.
I've tried also to place = instead :, but the result is the same.

Related

extra words after "else" clause in "if" command for TCL code

I have a tcl code where -
if { $xyz == 43 } {
# 1. Set some variables
set my_filename_log "somename_log.txt"
if {[file exists $my_filename_log ]} {
file delete -force $my_filename_log
}
} # end of xyz = 43
I am getting error as - TCLERROR: wrong # args: extra words after "else" clause in "if" command while compiling -
if { $xyz == 43 } {
# 1. Set some variables...
Not sure what is wrong with this code, checked tcl documentation didnt find anything
In Tcl, for else if condition should be written without space as elseif. Otherwise you will get the error you have mentioned.
if {$xyz==1} {
puts "Yes"
} else if {$xyz==2} {
puts "No"
}
wrong # args: extra words after "else" clause in "if" command
In your code, you have used
} # end of xyz = 43
at the last line. You have to use ; to mark the end of the statements and then you can start the comments with #.
So, your code should be written as,
if { $xyz == 43 } {
# 1. Set some variables
set my_filename_log "somename_log.txt"
if {[file exists $my_filename_log ]} {
file delete -force $my_filename_log
}
}; # end of xyz = 43

Autohotkey script - hotstring prevents if statement from working

:*:pl::pleaseHelpMe ; hotstring
:*:rf::reallyConfused ; hotstring
toggle := 0
\::
if (toggle = 0)
{
Run "https://www.google.com.sg/"
}
return
The code above does not work for the keystroke '\'
However, the code below works without the hotstrings
toggle := 0
\::
if (toggle = 0)
{
Run "https://www.google.com.sg/"
}
return
Why is that so? And how do I circumvent it and have the use of my hotstrings and the keystroke '\' to open google. Thanks a billion!!
You cannot define a variable between hotkeys or hotstrings.
A variable has to be defined
in the auto executable section of the script (top of the script,
before the first return or hotkey),
or in a hotkey,
or in a function.
Example:
; top of the script:
toggle := 0
return ; end of auto-execute section
; toggling a variable:
F1:: toggle := !toggle ; Pressing F1 changes the value of the variable "toggle" between 1 (true) and 0 (false)
:*:pl::pleaseHelpMe ; hotstring
:*:rf::reallyConfused ; hotstring
\::
if (toggle) ; If the value of the variable "toggle" is 1 (true)
Run "https://www.google.com.sg/"
else
Send, \
return
user3419297 is wrong. AutoHotkey does not need to define a variable prior to it's use. If a variable isn't defined it is automatically given a value of False or 0 during an evaluation.
This code works, I only added $ option to the hotkey to prevent the hotkey from triggering itself:
; toggling a variable:
F1:: toggle := !toggle ; Pressing F1 changes the value of the variable "toggle" between 1 (true) and 0 (false)
:*:pl::pleaseHelpMe ; hotstring
:*:rf::reallyConfused ; hotstring
$\::
if (toggle) ; If the value of the variable "toggle" is 1 (true)
Run "https://www.google.com.sg/"
else
Send, \
return
esc::exitApp

Flex RegEx to find string not starting with a pattern

I'm writing a lexer to scan a modified version of an INI file.
I need to recognize the declaration of variables, comments and strings (between double quotes) to be assigned to a variable. For example, this is correct:
# this is a comment
var1 = "string value"
I've successfully managed to recognize these tokens forcing the # at the begging of the comment regular expression and " at the end of the string regular expression, but I don't want to do this because later on, using Bison, the tokens I get are exactly # this is a comment and "string value". Instead I want this is a comment (without #) and string value (without ")
These are the regular expressions that I currently use:
[a-zA-Z][a-zA-Z0-9]* { return TOKEN_VAR_NAME; }
["][^\n\r]*["] { return TOKEN_STRING; }
[#][^\n\r]* { return TOKEN_COMMENT; }
Obviously there can be any number of white spaces, as well as tabs, inside the string, the comment and between the variable name and the =.
How could I achieve the result I want?
Maybe it will be easier if I show you a complete example of a correct input file and also the grammar rules I use with Flex and Bison.
Correct input file example:
[section1]
var1 = "string value"
var2 = "var1 = text"
# this is a comment
# var5 = "some text" this is also a valid comment
These are the regular expressions for the lexer:
"[" { return TOKEN::SECTION_START; }
"]" { return TOKEN::SECTION_END; }
"=" { return TOKEN::ASSIGNMENT; }
[#][^\n\r]* { return TOKEN::COMMENT; }
[a-zA-Z][a-zA-Z0-9]* { *m_yylval = yytext; return TOKEN::ID; }
["][^\n\r]*["] { *m_yylval = yytext; return TOKEN::STRING; }
And these are the syntax rules:
input : input line
| line
;
line : section
| value
| comment
;
section : SECTION_START ID SECTION_END { createNewSection($2); }
;
value : ID ASSIGNMENT STRING { addStringValue($1, $3); }
;
comment : COMMENT { addComment($1); }
;
To do that you have to treat " and # as different tokens (so they get scanned as individual tokens, different from the one you are scanning now) and use a %s or %x start condition to change the accepted regular patterns on reading those tokens with the scanner input.
This adds another drawback, that is, you will receive # as an individual token before the comment and " before and after the string contents, and you'll have to cope with that in your grammar. This will complicate your grammar and the scanner, so I have to discourage you to follow this approach.
There is a better solution, by writting a routine to unescape things and allow the scanner to be simpler by returning all the input string in yytext and simply
m_yylval = unescapeString(yytext); /* drop the " chars */
return STRING;
or
m_yylval = uncomment(yytext); /* drop the # at the beginning */
return COMMENT; /* return EOL if you are trying the exmample at the end */
in the yylex(); function.
Note
As comments are normally ignored, the best thing is to ignore using a rule like:
"#".* ; /* ignored */
in your flex file. This makes generated scanner not return and ignore the token just read.
Note 2
You probably don't have taken into account that your parser will allow you to introduce lines on the form:
var = "data"
in front of any
[section]
line, so you'll run into trouble trying to addStringvalue(...); when no section has been created. One possible solution is to modify your grammar to separate file in sections and force them to begin with a section line, like:
compilation: file comments ;
file: file section
| ; /* empty */
section: section_header section_body;
section_header: comments `[` ident `]` EOL
section_body: section_body comments assignment
| ; /* empty */
comments: comments COMMENT
| ; /* empty */
This has complicated by the fact that you want to process the comments. If you were to ignore them (with using ; in the flex scanner) The grammar would be:
file: empty_lines file section
| ; /* empty */
empty_lines: empty_lines EOL
| ; /* empty */
section: header body ;
header: '[' IDENT ']' EOL ;
body: body assignment
| ; /* empty */
assignment: IDENT '=' strings EOL
| EOL ; /* empty lines or lines with comments */
strings:
strings unit
| unit ;
unit: STRING
| IDENT
| NUMBER ;
This way the first thing allowed in your file is, apart of comments, that are ignored and blank space (EOLs are not considered blank space as we cannot ignore them, they terminate lines)

Bison outputting string after the wrong line

The input
1 -- Narrowing Variable Initialization
2
3 function main a: integer returns integer;
4 b: integer is a * 2.;
5 begin
6 if a <= 0 then
7 b + 3;
8 else
9 b * 4;
10 endif;
11 end;
is yielding the output
1 -- Narrowing Variable Initialization
2
3 function main a: integer returns integer;
4 b: integer is a * 2.;
5 begin
Narrowing Variable Initialization
6 if a <= 0 then
7 b + 3;
8 else
9 b * 4;
10 endif;
11 end;
Instead of placing that error message under line 4, which is where the error actually occurs. I've looked at it for hours and can't figure it out.
%union
{
char* ident;
Types types;
}
%token <ident> IDENTIFIER
%token <types> INTEGER_LITERAL
%token <types> REAL_LITERAL
%token BEGIN_
%token FUNCTION
%token IS
%token <types> INTEGER
%token <types> REAL
%token RETURNS
%type <types> expression
%type <types> factor
%type <types> literal
%type <types> term
%type <types> statement
%type <types> type
%type <types> variable
%%
program:
/* empty */ |
functions ;
functions:
function_header_recovery body ; |
function_header_recovery body functions ;
function_header_recovery:
function_header ';' |
error ';' ;
function_header:
FUNCTION {locals = new Locals();} IDENTIFIER optional_parameters RETURNS type {globals->insert($3,locals->tList);} ;
optional_parameters:
/* empty */ |
parameters;
parameters:
IDENTIFIER ':' type {locals->insert($1, $3); locals->tList.push_back($3); } |
IDENTIFIER ':' type {locals->insert($1, $3); locals->tList.push_back($3); } "," parameters;
type:
INTEGER | REAL ;
body:
optional_variables BEGIN_ statement END ';' ;
optional_variables:
/* empty */ |
variables ;
variables:
variable IS statement {checkTypes($1, $3, 2);} |
variable IS statement {checkTypes($1, $3, 2);} variables ;
variable:
IDENTIFIER ':' type {locals->insert($1, $3);} {$$ = $3;} ;
statement:
expression ';' |
...
Types checkTypes(Types left, Types right, int flag)
{
if (left == right)
{
return left;
}
if (flag == 1)
{
Listing::appendError("Conditional Expression Type Mismatch", Listing::SEMANTIC);
}
else if (flag == 2)
{
if (left < right)
{
Listing::appendError("Narrowing Variable Initialization", Listing::SEMANTIC);
}
}
return REAL_TYPE;
}
printing being handled by:
void Listing::nextLine()
{
printf("\n");
if (error == "")
{
lineNo++;
printf("%4d%s",lineNo," ");
}
else
{
printf("%s", error.c_str());
error = "";
nextLine();
}
}
void Listing::appendError(const char* errText, int errEnum)
{
error = error + errText;
if (errEnum == 997)
{
lexErrCount++;
}
else if (errEnum == 998)
{
synErrCount++;
}
else if (errEnum == 999)
{
semErrCount++;
}
}
void Listing::display()
{
printf( "\b\b\b\b\b\b " );
if (lexErrCount + synErrCount + semErrCount > 0)
{
printf("\n\n%s%d","Lexical Errors ",lexErrCount);
printf("\n%s%d","Syntax Errors ",synErrCount);
printf("\n%s%d\n","Semantic Errors ",semErrCount);
}
else
{
printf("\nCompiled Successfully\n");
}
}
That's just the way bison works. It produces a one-token lookahead parser, so your production actions don't get triggered until it has read the token following the production. Consequently, begin must be read before the action associated with variables happens. (bison never tries to combine actions, even if they are textually identical. So it really cannot know which variables production applies and which action to execute until it sees the following token.)
There are various ways to associate a line number and/or column position with each token, and to use that information when an error message is to be produced. Interspersing the errors and/or warnings with the input text, in general, requires buffering the input; for syntax errors, you only need to buffer until the next token but that is not a general solution; in some cases, for example, you may want to associate an error with an operator, for example, but the error won't be detected until the operator's trailing argument has been parsed.
A simple technique to correctly intersperse errors/warnings with source is to write all the errors/warnings to a temporary file, putting the file offset at the front of each error. This file can then be sorted, and the input can then be reread, inserting the error messages at appropriate points. The nice thing about this strategy is that it avoids having to maintain line numbers for each error, which noticeably slows down lexical analysis. Of course, it won't work so easily if you allow constructs like C's #include.
Because generating good error messages is hard, and even tracking locations can slow parsing down quite a bit, I've sometimes used the strategy of parsing input twice if an error is detected. The first parse only detects errors and fails early if it can't do anything more reasonable; if an error is detected, the input is reparsed with a more elaborate parser which carefully tracks file locations and possibly even uses heuristics like indentation depth to try to produce better error messages.
As rici notes, bison produces an LALR(1) parser, so it uses one token of lookahead to know what action to take. However, it doesn't ALWAYS use a token of lookahead -- in some cases (where there's only one possibility regardless of lookahead), it uses default reductions which can reduce a rule (and run the associated action) WITHOUT lookahead.
In your case, you can take advantage of that to get the action to run without lookahead if you really need to. The particular rule in question (which triggers the requirement for lookahead) is:
variables:
variable IS statement {checkTypes($1, $3, 2);} |
variable IS statement {checkTypes($1, $3, 2);} variables ;
in this case, after seeing a variable IS statement, it needs to see the next token to decide if there are more variable declarations in order to know which action (the first or the second) to run. But as the two actions are really the same, you could combine them into a single action:
variables: vardecl | vardecl variables ;
vardecl: variable IS statement {checkTypes($1, $3, 2);}
which would end up using a default reduction as it doesn't need the lookahead to decide between two reductions/actions.
Note that the above depends on being able to find the end of a statement without lookahead, which should be the case as long as all statements end unambiguously with a ;

Is this an unexpected keyword

I'm inside of a ColdFusion custom tag, and this line
20 : param attributes.name = "";
21 : param attributes.id = attributes.name;
22 : param attributes.inline false;
23 : param attributes.look = "";
24 : param attributes.processed = true;
Update
This is OK
22 : if(!structKeyExists(attributes, "inline")) attributes["inline"] = false;
Gets an error
You cannot use a variable reference with "." operators in this context
The CFML compiler was processing:
A script statement beginning with param on line 22, column 9.
A script statement beginning with { on line 12, column 36.
A script statement beginning with switch on line 12, column 1.
A cfscript tag beginning on line 6, column 2.
Is this a keyword? If so what is it?
You have missed equal to (=) operator on line 22.
Instead of
param attributes.inline false;
Write
param attributes.inline = false;